| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073 | /*============================================================================  CMake - Cross Platform Makefile Generator  Copyright 2004-2011 Kitware, Inc.  Copyright 2011 Alexander Neundorf ([email protected])  Distributed under the OSI-approved BSD License (the "License");  see accompanying file Copyright.txt for details.  This software is distributed WITHOUT ANY WARRANTY; without even the  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the License for more information.============================================================================*/#include "cmQtAutoGeneratorInitializer.h"#include "cmLocalGenerator.h"#include "cmMakefile.h"#include "cmSourceFile.h"#include <sys/stat.h>#include <cmsys/FStream.hxx>#if defined(_WIN32) && !defined(__CYGWIN__)# include "cmGlobalVisualStudioGenerator.h"#endifstatic void SetupSourceFiles(cmGeneratorTarget const* target,                                   std::vector<std::string>& skipMoc,                                   std::vector<std::string>& mocSources,                                   std::vector<std::string>& mocHeaders,                                   std::vector<std::string>& skipUic){  cmMakefile* makefile = target->Target->GetMakefile();  std::vector<cmSourceFile*> srcFiles;  target->GetConfigCommonSourceFiles(srcFiles);  std::vector<std::string> newRccFiles;  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();      fileIt != srcFiles.end();      ++fileIt)    {    cmSourceFile* sf = *fileIt;    std::string absFile = cmsys::SystemTools::GetRealPath(                                                    sf->GetFullPath());    bool skipFileForMoc =        cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));    bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));    if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))      {      skipUic.push_back(absFile);      }    std::string ext = sf->GetExtension();    if (target->GetPropertyAsBool("AUTORCC"))      {      if (ext == "qrc"          && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))        {        std::string basename = cmsys::SystemTools::                                      GetFilenameWithoutLastExtension(absFile);        std::string rcc_output_dir = target->GetSupportDirectory();        cmSystemTools::MakeDirectory(rcc_output_dir.c_str());        std::string rcc_output_file = rcc_output_dir;        rcc_output_file += "/qrc_" + basename + ".cpp";        makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",                                rcc_output_file.c_str(), false);        makefile->GetOrCreateSource(rcc_output_file, true);        newRccFiles.push_back(rcc_output_file);        }      }    if (!generated)      {      if (skipFileForMoc)        {        skipMoc.push_back(absFile);        }      else        {        cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(                                                                ext.c_str());        if (fileType == cmSystemTools::CXX_FILE_FORMAT)          {          mocSources.push_back(absFile);          }        else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)          {          mocHeaders.push_back(absFile);          }        }      }    }  for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();      fileIt != newRccFiles.end();      ++fileIt)    {    const_cast<cmGeneratorTarget*>(target)->AddSource(*fileIt);    }}static void GetCompileDefinitionsAndDirectories(  cmGeneratorTarget const* target,  const std::string& config,  std::string &incs,  std::string &defs){  std::vector<std::string> includeDirs;  cmLocalGenerator *localGen = target->GetLocalGenerator();  // Get the include dirs for this target, without stripping the implicit  // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667  localGen->GetIncludeDirectories(includeDirs, target, "CXX", config, false);  incs = cmJoin(includeDirs, ";");  std::set<std::string> defines;  localGen->AddCompileDefinitions(defines, target, config, "CXX");  defs += cmJoin(defines, ";");}static void SetupAutoMocTarget(cmGeneratorTarget const* target,                          const std::string &autogenTargetName,                          std::vector<std::string> const& skipMoc,                          std::vector<std::string> const& mocHeaders,                          std::map<std::string, std::string> &configIncludes,                          std::map<std::string, std::string> &configDefines){  cmLocalGenerator* lg = target->GetLocalGenerator();  cmMakefile* makefile = target->Target->GetMakefile();  const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");  std::string _moc_options = (tmp!=0 ? tmp : "");  makefile->AddDefinition("_moc_options",          cmOutputConverter::EscapeForCMake(_moc_options).c_str());  makefile->AddDefinition("_skip_moc",          cmOutputConverter::EscapeForCMake(cmJoin(skipMoc, ";")).c_str());  makefile->AddDefinition("_moc_headers",          cmOutputConverter::EscapeForCMake(cmJoin(mocHeaders, ";")).c_str());  bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");  makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");  std::string _moc_incs;  std::string _moc_compile_defs;  std::vector<std::string> configs;  const std::string& config = makefile->GetConfigurations(configs);  GetCompileDefinitionsAndDirectories(target, config,                                      _moc_incs, _moc_compile_defs);  makefile->AddDefinition("_moc_incs",          cmOutputConverter::EscapeForCMake(_moc_incs).c_str());  makefile->AddDefinition("_moc_compile_defs",          cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str());  for (std::vector<std::string>::const_iterator li = configs.begin();       li != configs.end(); ++li)    {    std::string config_moc_incs;    std::string config_moc_compile_defs;    GetCompileDefinitionsAndDirectories(target, *li,                                        config_moc_incs,                                        config_moc_compile_defs);    if (config_moc_incs != _moc_incs)      {      configIncludes[*li] =                    cmOutputConverter::EscapeForCMake(config_moc_incs);      if(_moc_incs.empty())        {        _moc_incs = config_moc_incs;        }      }    if (config_moc_compile_defs != _moc_compile_defs)      {      configDefines[*li] =            cmOutputConverter::EscapeForCMake(config_moc_compile_defs);      if(_moc_compile_defs.empty())        {        _moc_compile_defs = config_moc_compile_defs;        }      }    }  const char *qtVersion = makefile->GetDefinition("_target_qt_version");  if (strcmp(qtVersion, "5") == 0)    {    cmGeneratorTarget *qt5Moc =        lg->FindGeneratorTargetToUse("Qt5::moc");    if (!qt5Moc)      {      cmSystemTools::Error("Qt5::moc target not found ",                          autogenTargetName.c_str());      return;      }    makefile->AddDefinition("_qt_moc_executable",                            qt5Moc->ImportedGetLocation(""));    }  else if (strcmp(qtVersion, "4") == 0)    {    cmGeneratorTarget *qt4Moc =        lg->FindGeneratorTargetToUse("Qt4::moc");    if (!qt4Moc)      {      cmSystemTools::Error("Qt4::moc target not found ",                          autogenTargetName.c_str());      return;      }    makefile->AddDefinition("_qt_moc_executable",                            qt4Moc->ImportedGetLocation(""));    }  else    {    cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "                        "Qt 5 ", autogenTargetName.c_str());    }}static void GetUicOpts(cmGeneratorTarget const* target,                       const std::string& config,                       std::string &optString){  std::vector<std::string> opts;  target->GetAutoUicOptions(opts, config);  optString = cmJoin(opts, ";");}static void SetupAutoUicTarget(cmGeneratorTarget const* target,                          std::vector<std::string> const& skipUic,                          std::map<std::string, std::string> &configUicOptions){  cmLocalGenerator* lg = target->GetLocalGenerator();  cmMakefile *makefile = target->Target->GetMakefile();  std::set<std::string> skipped;  skipped.insert(skipUic.begin(), skipUic.end());  makefile->AddDefinition("_skip_uic",          cmOutputConverter::EscapeForCMake(cmJoin(skipUic, ";")).c_str());  std::vector<cmSourceFile*> uiFilesWithOptions                                        = makefile->GetQtUiFilesWithOptions();  const char *qtVersion = makefile->GetDefinition("_target_qt_version");  std::string _uic_opts;  std::vector<std::string> configs;  const std::string& config = makefile->GetConfigurations(configs);  GetUicOpts(target, config, _uic_opts);  if (!_uic_opts.empty())    {    _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);    makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());    }  for (std::vector<std::string>::const_iterator li = configs.begin();       li != configs.end(); ++li)    {    std::string config_uic_opts;    GetUicOpts(target, *li, config_uic_opts);    if (config_uic_opts != _uic_opts)      {      configUicOptions[*li] =                    cmOutputConverter::EscapeForCMake(config_uic_opts);      if(_uic_opts.empty())        {        _uic_opts = config_uic_opts;        }      }    }  std::string uiFileFiles;  std::string uiFileOptions;  const char* sep = "";  for(std::vector<cmSourceFile*>::const_iterator fileIt =      uiFilesWithOptions.begin();      fileIt != uiFilesWithOptions.end();      ++fileIt)    {    cmSourceFile* sf = *fileIt;    std::string absFile = cmsys::SystemTools::GetRealPath(                                                    sf->GetFullPath());    if (!skipped.insert(absFile).second)      {      continue;      }    uiFileFiles += sep;    uiFileFiles += absFile;    uiFileOptions += sep;    std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");    cmSystemTools::ReplaceString(opts, ";", "@list_sep@");    uiFileOptions += opts;    sep = ";";    }  makefile->AddDefinition("_qt_uic_options_files",              cmOutputConverter::EscapeForCMake(uiFileFiles).c_str());  makefile->AddDefinition("_qt_uic_options_options",            cmOutputConverter::EscapeForCMake(uiFileOptions).c_str());  std::string targetName = target->GetName();  if (strcmp(qtVersion, "5") == 0)    {    cmGeneratorTarget *qt5Uic =        lg->FindGeneratorTargetToUse("Qt5::uic");    if (!qt5Uic)      {      // Project does not use Qt5Widgets, but has AUTOUIC ON anyway      }    else      {      makefile->AddDefinition("_qt_uic_executable",                              qt5Uic->ImportedGetLocation(""));      }    }  else if (strcmp(qtVersion, "4") == 0)    {    cmGeneratorTarget *qt4Uic =        lg->FindGeneratorTargetToUse("Qt4::uic");    if (!qt4Uic)      {      cmSystemTools::Error("Qt4::uic target not found ",                          targetName.c_str());      return;      }    makefile->AddDefinition("_qt_uic_executable",                            qt4Uic->ImportedGetLocation(""));    }  else    {    cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "                        "Qt 5 ", targetName.c_str());    }}static std::string GetRccExecutable(cmGeneratorTarget const* target){  cmLocalGenerator* lg = target->GetLocalGenerator();  cmMakefile *makefile = target->Target->GetMakefile();  const char *qtVersion = makefile->GetDefinition("_target_qt_version");  if (!qtVersion)    {    qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");    if (!qtVersion)      {      qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");      }    if (const char *targetQtVersion =        target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",                                                        ""))      {      qtVersion = targetQtVersion;      }    }  std::string targetName = target->GetName();  if (strcmp(qtVersion, "5") == 0)    {    cmGeneratorTarget *qt5Rcc =        lg->FindGeneratorTargetToUse("Qt5::rcc");    if (!qt5Rcc)      {      cmSystemTools::Error("Qt5::rcc target not found ",                          targetName.c_str());      return std::string();      }    return qt5Rcc->ImportedGetLocation("");    }  else if (strcmp(qtVersion, "4") == 0)    {    cmGeneratorTarget *qt4Rcc =        lg->FindGeneratorTargetToUse("Qt4::rcc");    if (!qt4Rcc)      {      cmSystemTools::Error("Qt4::rcc target not found ",                          targetName.c_str());      return std::string();      }    return qt4Rcc->ImportedGetLocation("");    }  cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "                      "Qt 5 ", targetName.c_str());  return std::string();}static void MergeRccOptions(std::vector<std::string> &opts,                         const std::vector<std::string> &fileOpts,                         bool isQt5){  static const char* valueOptions[] = {    "name",    "root",    "compress",    "threshold"  };  std::vector<std::string> extraOpts;  for(std::vector<std::string>::const_iterator it = fileOpts.begin();      it != fileOpts.end(); ++it)    {    std::vector<std::string>::iterator existingIt                                  = std::find(opts.begin(), opts.end(), *it);    if (existingIt != opts.end())      {      const char *o = it->c_str();      if (*o == '-')        {        ++o;        }      if (isQt5 && *o == '-')        {        ++o;        }      if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),                  cmStrCmp(*it)) != cmArrayEnd(valueOptions))        {        assert(existingIt + 1 != opts.end());        *(existingIt + 1) = *(it + 1);        ++it;        }      }    else      {      extraOpts.push_back(*it);      }    }  opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());}std::string GetAutogenTargetName(    cmGeneratorTarget const* target){  std::string autogenTargetName = target->GetName();  autogenTargetName += "_automoc";  return autogenTargetName;}std::string GetAutogenTargetDir(    cmGeneratorTarget const* target){  cmMakefile* makefile = target->Target->GetMakefile();  std::string targetDir = makefile->GetCurrentBinaryDirectory();  targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();  targetDir += "/";  targetDir += GetAutogenTargetName(target);  targetDir += ".dir/";  return targetDir;}static void copyTargetProperty(cmTarget* destinationTarget,                               cmTarget* sourceTarget,                               const std::string& propertyName){  const char* propertyValue = sourceTarget->GetProperty(propertyName);  if (propertyValue)    {    destinationTarget->SetProperty(propertyName, propertyValue);    }}static std::string cmQtAutoGeneratorsStripCR(std::string const& line){  // Strip CR characters rcc may have printed (possibly more than one!).  std::string::size_type cr = line.find('\r');  if (cr != line.npos)    {    return line.substr(0, cr);    }  return line;}static std::string ReadAll(const std::string& filename){  cmsys::ifstream file(filename.c_str());  std::stringstream stream;  stream << file.rdbuf();  file.close();  return stream.str();}static std::string ListQt5RccInputs(cmSourceFile* sf,                                            cmGeneratorTarget const* target,                                            std::vector<std::string>& depends){  std::string rccCommand      = GetRccExecutable(target);  bool hasDashDashList = false;  {  std::vector<std::string> command;  command.push_back(rccCommand);  command.push_back("--help");  std::string rccStdOut;  std::string rccStdErr;  int retVal = 0;  bool result = cmSystemTools::RunSingleCommand(    command, &rccStdOut, &rccStdErr,    &retVal, 0, cmSystemTools::OUTPUT_NONE);  if (result && retVal == 0 &&      rccStdOut.find("--list") != std::string::npos)    {    hasDashDashList = true;    }  }  std::vector<std::string> qrcEntries;  std::vector<std::string> command;  command.push_back(rccCommand);  command.push_back(hasDashDashList? "--list" : "-list");  std::string absFile = cmsys::SystemTools::GetRealPath(                                              sf->GetFullPath());  command.push_back(absFile);  std::string rccStdOut;  std::string rccStdErr;  int retVal = 0;  bool result = cmSystemTools::RunSingleCommand(    command, &rccStdOut, &rccStdErr,    &retVal, 0, cmSystemTools::OUTPUT_NONE);  if (!result || retVal)    {    std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()              << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl;    return std::string();    }  {  std::istringstream ostr(rccStdOut);  std::string oline;  while(std::getline(ostr, oline))    {    oline = cmQtAutoGeneratorsStripCR(oline);    if(!oline.empty())      {      qrcEntries.push_back(oline);      }    }  }  {  std::istringstream estr(rccStdErr);  std::string eline;  while(std::getline(estr, eline))    {    eline = cmQtAutoGeneratorsStripCR(eline);    if (cmHasLiteralPrefix(eline, "RCC: Error in"))      {      static std::string searchString = "Cannot find file '";      std::string::size_type pos = eline.find(searchString);      if (pos == std::string::npos)        {        std::cerr << "AUTOGEN: error: Rcc lists unparsable output "                  << eline << std::endl;        return std::string();        }      pos += searchString.length();      std::string::size_type sz = eline.size() - pos - 1;      qrcEntries.push_back(eline.substr(pos, sz));      }    }  }  depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());  return cmJoin(qrcEntries, "@list_sep@");}static std::string ListQt4RccInputs(cmSourceFile* sf,                                            std::vector<std::string>& depends){  const std::string qrcContents = ReadAll(sf->GetFullPath());  cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");  std::string entriesList;  const char* sep = "";  size_t offset = 0;  while (fileMatchRegex.find(qrcContents.c_str() + offset))    {    std::string qrcEntry = fileMatchRegex.match(1);    offset += qrcEntry.size();    cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");    fileReplaceRegex.find(qrcEntry);    std::string tag = fileReplaceRegex.match(1);    qrcEntry = qrcEntry.substr(tag.size());    if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str()))      {      qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;      }    entriesList += sep;    entriesList += qrcEntry;    sep = "@list_sep@";    depends.push_back(qrcEntry);    }  return entriesList;}static void SetupAutoRccTarget(cmGeneratorTarget const* target){  std::string _rcc_files;  const char* sepRccFiles = "";  cmMakefile *makefile = target->Target->GetMakefile();  std::vector<cmSourceFile*> srcFiles;  target->GetConfigCommonSourceFiles(srcFiles);  std::string qrcInputs;  const char* qrcInputsSep = "";  std::string rccFileFiles;  std::string rccFileOptions;  const char *optionSep = "";  const char *qtVersion = makefile->GetDefinition("_target_qt_version");  std::vector<std::string> rccOptions;  if (const char* opts = target->GetProperty("AUTORCC_OPTIONS"))    {    cmSystemTools::ExpandListArgument(opts, rccOptions);    }  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");  if (qtMajorVersion == "")    {    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");    }  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());      bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));      if (!skip)        {        _rcc_files += sepRccFiles;        _rcc_files += absFile;        sepRccFiles = ";";        if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))          {          std::vector<std::string> optsVec;          cmSystemTools::ExpandListArgument(prop, optsVec);          MergeRccOptions(rccOptions, optsVec,                                strcmp(qtVersion, "5") == 0);          }        if (!rccOptions.empty())          {          rccFileFiles += optionSep;          rccFileFiles += absFile;          rccFileOptions += optionSep;          }        const char *listSep = "";        for(std::vector<std::string>::const_iterator it = rccOptions.begin();            it != rccOptions.end();            ++it)          {          rccFileOptions += listSep;          rccFileOptions += *it;          listSep = "@list_sep@";          }        optionSep = ";";        std::vector<std::string> depends;        std::string entriesList;        if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))          {          if (qtMajorVersion == "5")            {            entriesList = ListQt5RccInputs(sf, target, depends);            }          else            {            entriesList = ListQt4RccInputs(sf, depends);            }          if (entriesList.empty())            {            return;            }          }        qrcInputs += qrcInputsSep;        qrcInputs += entriesList;        qrcInputsSep = ";";        }      }    }  makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),                      cmOutputConverter::EscapeForCMake(qrcInputs).c_str());  makefile->AddDefinition("_rcc_files",          cmOutputConverter::EscapeForCMake(_rcc_files).c_str());  makefile->AddDefinition("_qt_rcc_options_files",              cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());  makefile->AddDefinition("_qt_rcc_options_options",            cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());  makefile->AddDefinition("_qt_rcc_executable",              GetRccExecutable(target).c_str());}void cmQtAutoGeneratorInitializer::InitializeAutogenSources(    cmGeneratorTarget* target){  cmMakefile* makefile = target->Target->GetMakefile();  if (target->GetPropertyAsBool("AUTOMOC"))    {    std::string automocTargetName = GetAutogenTargetName(target);    std::string mocCppFile = makefile->GetCurrentBinaryDirectory();    mocCppFile += "/";    mocCppFile += automocTargetName;    mocCppFile += ".cpp";    makefile->GetOrCreateSource(mocCppFile, true);    makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",                            mocCppFile.c_str(), false);    target->AddSource(mocCppFile);    }}void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(                                                 cmLocalGenerator* lg,                                                 cmGeneratorTarget* target){  cmMakefile* makefile = target->Target->GetMakefile();  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");  if (qtMajorVersion == "")    {    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");    }  // create a custom target for running generators at buildtime:  std::string autogenTargetName = GetAutogenTargetName(target);  std::string targetDir = GetAutogenTargetDir(target);  cmCustomCommandLine currentLine;  currentLine.push_back(cmSystemTools::GetCMakeCommand());  currentLine.push_back("-E");  currentLine.push_back("cmake_autogen");  currentLine.push_back(targetDir);  currentLine.push_back("$<CONFIGURATION>");  cmCustomCommandLines commandLines;  commandLines.push_back(currentLine);  std::string workingDirectory = cmSystemTools::CollapseFullPath(                                    "", makefile->GetCurrentBinaryDirectory());  std::vector<std::string> depends;  if (const char *autogenDepends =                                target->GetProperty("AUTOGEN_TARGET_DEPENDS"))    {    cmSystemTools::ExpandListArgument(autogenDepends, depends);    }  std::vector<std::string> toolNames;  if (target->GetPropertyAsBool("AUTOMOC"))    {    toolNames.push_back("moc");    }  if (target->GetPropertyAsBool("AUTOUIC"))    {    toolNames.push_back("uic");    }  if (target->GetPropertyAsBool("AUTORCC"))    {    toolNames.push_back("rcc");    }  std::string tools = toolNames[0];  toolNames.erase(toolNames.begin());  while (toolNames.size() > 1)    {    tools += ", " + toolNames[0];    toolNames.erase(toolNames.begin());    }  if (toolNames.size() == 1)    {    tools += " and " + toolNames[0];    }  std::string autogenComment = "Automatic " + tools + " for target ";  autogenComment += target->GetName();#if defined(_WIN32) && !defined(__CYGWIN__)  bool usePRE_BUILD = false;  cmGlobalGenerator* gg = lg->GetGlobalGenerator();  if(gg->GetName().find("Visual Studio") != std::string::npos)    {    cmGlobalVisualStudioGenerator* vsgg =      static_cast<cmGlobalVisualStudioGenerator*>(gg);    // Under VS >= 7 use a PRE_BUILD event instead of a separate target to    // reduce the number of targets loaded into the IDE.    // This also works around a VS 11 bug that may skip updating the target:    //  https://connect.microsoft.com/VisualStudio/feedback/details/769495    usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;    if(usePRE_BUILD)      {      for (std::vector<std::string>::iterator it = depends.begin();            it != depends.end(); ++it)        {        if(!makefile->FindTargetToUse(it->c_str()))          {          usePRE_BUILD = false;          break;          }        }      }    }#endif  std::vector<std::string> rcc_output;  bool const isNinja =    lg->GetGlobalGenerator()->GetName() == "Ninja";  if(isNinja#if defined(_WIN32) && !defined(__CYGWIN__)        || usePRE_BUILD#endif        )    {    std::vector<cmSourceFile*> srcFiles;    target->GetConfigCommonSourceFiles(srcFiles);    for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();        fileIt != srcFiles.end();        ++fileIt)      {      cmSourceFile* sf = *fileIt;      std::string absFile = cmsys::SystemTools::GetRealPath(                                                sf->GetFullPath());      std::string ext = sf->GetExtension();      if (target->GetPropertyAsBool("AUTORCC"))        {        if (ext == "qrc"            && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))          {          std::string basename = cmsys::SystemTools::                                  GetFilenameWithoutLastExtension(absFile);          std::string rcc_output_dir = target->GetSupportDirectory();          cmSystemTools::MakeDirectory(rcc_output_dir.c_str());          std::string rcc_output_file = rcc_output_dir;          rcc_output_file += "/qrc_" + basename + ".cpp";          rcc_output.push_back(rcc_output_file);          if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))            {            if (qtMajorVersion == "5")              {              ListQt5RccInputs(sf, target, depends);              }            else              {              ListQt4RccInputs(sf, depends);              }#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            }          }        }      }    }#if defined(_WIN32) && !defined(__CYGWIN__)  if(usePRE_BUILD)    {    // Add the pre-build command directly to bypass the OBJECT_LIBRARY    // rejection in cmMakefile::AddCustomCommandToTarget because we know    // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.    std::vector<std::string> no_output;    std::vector<std::string> no_byproducts;    cmCustomCommand cc(makefile, no_output, no_byproducts, depends,                       commandLines, autogenComment.c_str(),                       workingDirectory.c_str());    cc.SetEscapeOldStyle(false);    cc.SetEscapeAllowMakeVars(true);    target->Target->AddPreBuildCommand(cc);    }  else#endif    {    cmTarget* autogenTarget = makefile->AddUtilityCommand(                                autogenTargetName, true,                                workingDirectory.c_str(),                                /*byproducts=*/rcc_output, depends,                                commandLines, false, autogenComment.c_str());    cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);    lg->AddGeneratorTarget(gt);    lg->GetGlobalGenerator()->AddGeneratorTarget(autogenTarget, gt);    // Set target folder    const char* autogenFolder = makefile->GetState()                                ->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");    if (!autogenFolder)      {      autogenFolder = makefile->GetState()                                ->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");      }    if (autogenFolder && *autogenFolder)      {      autogenTarget->SetProperty("FOLDER", autogenFolder);      }    else      {      // inherit FOLDER property from target (#13688)      copyTargetProperty(gt->Target, target->Target, "FOLDER");      }    target->Target->AddUtility(autogenTargetName);    }}void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(    cmGeneratorTarget const* target){  cmMakefile* makefile = target->Target->GetMakefile();  // forget the variables added here afterwards again:  cmMakefile::ScopePushPop varScope(makefile);  static_cast<void>(varScope);  // create a custom target for running generators at buildtime:  std::string autogenTargetName = GetAutogenTargetName(target);  makefile->AddDefinition("_moc_target_name",          cmOutputConverter::EscapeForCMake(autogenTargetName).c_str());  makefile->AddDefinition("_origin_target_name",          cmOutputConverter::EscapeForCMake(target->GetName()).c_str());  std::string targetDir = GetAutogenTargetDir(target);  const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");  if (!qtVersion)    {    qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");    }  if (const char *targetQtVersion =      target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))    {    qtVersion = targetQtVersion;    }  if (qtVersion)    {    makefile->AddDefinition("_target_qt_version", qtVersion);    }  std::vector<std::string> skipUic;  std::vector<std::string> skipMoc;  std::vector<std::string> mocSources;  std::vector<std::string> mocHeaders;  std::map<std::string, std::string> configIncludes;  std::map<std::string, std::string> configDefines;  std::map<std::string, std::string> configUicOptions;  if (target->GetPropertyAsBool("AUTOMOC")      || target->GetPropertyAsBool("AUTOUIC")      || target->GetPropertyAsBool("AUTORCC"))    {    SetupSourceFiles(target, skipMoc, mocSources, mocHeaders, skipUic);    }  makefile->AddDefinition("_cpp_files",          cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());  if (target->GetPropertyAsBool("AUTOMOC"))    {    SetupAutoMocTarget(target, autogenTargetName,                             skipMoc, mocHeaders,                             configIncludes, configDefines);    }  if (target->GetPropertyAsBool("AUTOUIC"))    {    SetupAutoUicTarget(target, skipUic, configUicOptions);    }  if (target->GetPropertyAsBool("AUTORCC"))    {    SetupAutoRccTarget(target);    }  const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");  std::string inputFile = cmakeRoot;  inputFile += "/Modules/AutogenInfo.cmake.in";  std::string outputFile = targetDir;  outputFile += "/AutogenInfo.cmake";  makefile->AddDefinition("_qt_rcc_inputs",              makefile->GetDefinition("_qt_rcc_inputs_" + target->GetName()));  makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),                          false, true, false);  // Ensure we have write permission in case .in was read-only.  mode_t perm = 0;#if defined(_WIN32) && !defined(__CYGWIN__)  mode_t mode_write = S_IWRITE;#else  mode_t mode_write = S_IWUSR;#endif  cmSystemTools::GetPermissions(outputFile, perm);  if (!(perm & mode_write))    {    cmSystemTools::SetPermissions(outputFile, perm | mode_write);    }  if (!configDefines.empty()      || !configIncludes.empty()      || !configUicOptions.empty())    {    cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);    if ( !infoFile )      {      std::string error = "Internal CMake error when trying to open file: ";      error += outputFile.c_str();      error += " for writing.";      cmSystemTools::Error(error.c_str());      return;      }    if (!configDefines.empty())      {      for (std::map<std::string, std::string>::iterator            it = configDefines.begin(), end = configDefines.end();            it != end; ++it)        {        infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<          " " << it->second << ")\n";        }      }    if (!configIncludes.empty())      {      for (std::map<std::string, std::string>::iterator            it = configIncludes.begin(), end = configIncludes.end();            it != end; ++it)        {        infoFile << "set(AM_MOC_INCLUDES_" << it->first <<          " " << it->second << ")\n";        }      }    if (!configUicOptions.empty())      {      for (std::map<std::string, std::string>::iterator            it = configUicOptions.begin(), end = configUicOptions.end();            it != end; ++it)        {        infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first <<          " " << it->second << ")\n";        }      }    }}
 |