summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-09-29 14:08:10 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2015-09-29 14:08:10 (GMT)
commitee1b04110866d1e6bddba2346c0cc19507fc6ed0 (patch)
treeb2671cfa3f7ef030d1bda040d0536dac6e82d5d8 /Source
parent6a072563d2c81f653986318882f9782469a58936 (diff)
parent1fe390201df041cebcfcb5e6cc401f8ece2d6072 (diff)
downloadCMake-ee1b04110866d1e6bddba2346c0cc19507fc6ed0.zip
CMake-ee1b04110866d1e6bddba2346c0cc19507fc6ed0.tar.gz
CMake-ee1b04110866d1e6bddba2346c0cc19507fc6ed0.tar.bz2
Merge topic 'simplify-qt-autogen'
1fe39020 QtAutogen: Port away from cmLocalGenerator. 59a729b2 QtAutogen: Split initializer class into separate file. 1e83a963 QtAutogen: Split initializer methods into separate class. 12f0e13c QtAutogen: Simplify generator initialization API. 65ff75d3 QtAutogen: Remove unnecessary dereference. 64b78c14 QtAutogen: Move Source initialization to prior loop. c3c20d3c QtAutogen: Add _automoc.cpp sources before initializing. 8b6ec29d QtAutogen: Move initialization condition to caller. 9470b056 QtAutogen: Move condition to prior loop. b7491b1c QtAutogen: Move condition to prior loop. e791c854 QtAutogen: Make some methods static. 6210ec64 QtAutogen: Make internal method private. a3ceb998 QtAutogen: Don't use members to initialize automoc targets. dced2fe1 QtAutogen: Rename variable. f9a77e76 QtAutogen: Don't use a member to store skipped uic files. c3633e7a QtAutogen: Add missing includes and forward declarations.
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/cmGlobalGenerator.cxx72
-rw-r--r--Source/cmGlobalGenerator.h5
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx1074
-rw-r--r--Source/cmQtAutoGeneratorInitializer.h67
-rw-r--r--Source/cmQtAutoGenerators.cxx1066
-rw-r--r--Source/cmQtAutoGenerators.h29
7 files changed, 1208 insertions, 1107 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e2a7ff2..ae5b03f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -327,6 +327,8 @@ set(SRCS
cmPropertyDefinitionMap.h
cmPropertyMap.cxx
cmPropertyMap.h
+ cmQtAutoGeneratorInitializer.cxx
+ cmQtAutoGeneratorInitializer.h
cmQtAutoGenerators.cxx
cmQtAutoGenerators.h
cmRST.cxx
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 3589e82..540bd01 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -22,7 +22,7 @@
#include "cmake.h"
#include "cmState.h"
#include "cmMakefile.h"
-#include "cmQtAutoGenerators.h"
+#include "cmQtAutoGeneratorInitializer.h"
#include "cmSourceFile.h"
#include "cmVersion.h"
#include "cmTargetExport.h"
@@ -1251,8 +1251,8 @@ bool cmGlobalGenerator::Compute()
#ifdef CMAKE_BUILD_WITH_CMAKE
// Iterate through all targets and set up automoc for those which have
// the AUTOMOC, AUTOUIC or AUTORCC property set
- AutogensType autogens;
- this->CreateQtAutoGeneratorsTargets(autogens);
+ std::vector<cmTarget const*> autogenTargets =
+ this->CreateQtAutoGeneratorsTargets();
#endif
unsigned int i;
@@ -1266,10 +1266,10 @@ bool cmGlobalGenerator::Compute()
this->InitGeneratorTargets();
#ifdef CMAKE_BUILD_WITH_CMAKE
- for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
- ++it)
+ for (std::vector<cmTarget const*>::iterator it = autogenTargets.begin();
+ it != autogenTargets.end(); ++it)
{
- it->first.SetupAutoGenerateTarget(it->second);
+ cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(*it);
}
#endif
@@ -1405,8 +1405,11 @@ bool cmGlobalGenerator::ComputeTargetDepends()
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
+std::vector<const cmTarget*>
+cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
{
+ std::vector<const cmTarget*> autogenTargets;
+
#ifdef CMAKE_BUILD_WITH_CMAKE
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
{
@@ -1421,37 +1424,48 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
{
continue;
}
+ if(ti->second.GetType() != cmTarget::EXECUTABLE &&
+ ti->second.GetType() != cmTarget::STATIC_LIBRARY &&
+ ti->second.GetType() != cmTarget::SHARED_LIBRARY &&
+ ti->second.GetType() != cmTarget::MODULE_LIBRARY &&
+ ti->second.GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ continue;
+ }
+ if((!ti->second.GetPropertyAsBool("AUTOMOC")
+ && !ti->second.GetPropertyAsBool("AUTOUIC")
+ && !ti->second.GetPropertyAsBool("AUTORCC"))
+ || ti->second.IsImported())
+ {
+ continue;
+ }
+ // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
+ cmMakefile* mf = ti->second.GetMakefile();
+ std::string qtMajorVersion = mf->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion == "")
+ {
+ qtMajorVersion = mf->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+ }
+ if (qtMajorVersion != "4" && qtMajorVersion != "5")
+ {
+ continue;
+ }
+
+ cmQtAutoGeneratorInitializer::InitializeAutogenSources(&ti->second);
targetNames.push_back(ti->second.GetName());
}
for(std::vector<std::string>::iterator ti = targetNames.begin();
ti != targetNames.end(); ++ti)
{
- cmTarget& target = *this->LocalGenerators[i]
+ cmTarget* target = this->LocalGenerators[i]
->GetMakefile()->FindTarget(*ti, true);
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::OBJECT_LIBRARY)
- {
- if((target.GetPropertyAsBool("AUTOMOC")
- || target.GetPropertyAsBool("AUTOUIC")
- || target.GetPropertyAsBool("AUTORCC"))
- && !target.IsImported())
- {
- cmQtAutoGenerators autogen;
- if(autogen.InitializeAutogenTarget(this->LocalGenerators[i],
- &target))
- {
- autogens.push_back(std::make_pair(autogen, &target));
- }
- }
- }
+ cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
+ this->LocalGenerators[i], target);
+ autogenTargets.push_back(target);
}
}
-#else
- (void)autogens;
#endif
+ return autogenTargets;
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index ba7bae3..88a03ca 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -41,7 +41,6 @@ class cmTarget;
class cmInstallTargetGenerator;
class cmInstallFilesGenerator;
class cmExportBuildFileGenerator;
-class cmQtAutoGenerators;
/** \class cmGlobalGenerator
* \brief Responsible for overseeing the generation process for the entire tree
@@ -385,9 +384,7 @@ protected:
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
- typedef std::vector<std::pair<cmQtAutoGenerators,
- cmTarget const*> > AutogensType;
- void CreateQtAutoGeneratorsTargets(AutogensType& autogens);
+ std::vector<cmTarget const*> CreateQtAutoGeneratorsTargets();
std::string SelectMakeProgram(const std::string& makeProgram,
const std::string& makeDefault = "") const;
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
new file mode 100644
index 0000000..24e7ed8
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -0,0 +1,1074 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ 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"
+#endif
+
+std::string cmQtAutoGeneratorInitializer::GetAutogenTargetName(
+ cmTarget const* target)
+{
+ std::string autogenTargetName = target->GetName();
+ autogenTargetName += "_automoc";
+ return autogenTargetName;
+}
+
+std::string cmQtAutoGeneratorInitializer::GetAutogenTargetDir(
+ cmTarget const* target)
+{
+ cmMakefile* makefile = target->GetMakefile();
+ std::string targetDir = makefile->GetCurrentBinaryDirectory();
+ targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
+ targetDir += "/";
+ targetDir += cmQtAutoGeneratorInitializer::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();
+}
+
+std::string cmQtAutoGeneratorInitializer::ListQt5RccInputs(cmSourceFile* sf,
+ cmTarget const* target,
+ std::vector<std::string>& depends)
+{
+ std::string rccCommand
+ = cmQtAutoGeneratorInitializer::GetRccExecutable(target);
+ std::vector<std::string> qrcEntries;
+
+ std::vector<std::string> command;
+ command.push_back(rccCommand);
+ command.push_back("-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@");
+}
+
+std::string cmQtAutoGeneratorInitializer::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;
+}
+
+
+void cmQtAutoGeneratorInitializer::InitializeAutogenSources(cmTarget* target)
+{
+ cmMakefile* makefile = target->GetMakefile();
+
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ std::string automocTargetName =
+ cmQtAutoGeneratorInitializer::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,
+ cmTarget* target)
+{
+ cmMakefile* makefile = 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 =
+ cmQtAutoGeneratorInitializer::GetAutogenTargetName(target);
+
+ std::string targetDir =
+ cmQtAutoGeneratorInitializer::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;
+ cmGeneratorTarget* gtgt =
+ lg->GetGlobalGenerator()->GetGeneratorTarget(target);
+ gtgt->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")
+ {
+ cmQtAutoGeneratorInitializer::ListQt5RccInputs(sf, target,
+ depends);
+ }
+ else
+ {
+ cmQtAutoGeneratorInitializer::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->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);
+ makefile->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(autogenTarget, target, "FOLDER");
+ }
+
+ target->AddUtility(autogenTargetName);
+ }
+}
+
+static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
+ const std::string& config,
+ std::string &incs,
+ std::string &defs)
+{
+ cmMakefile* makefile = target->GetMakefile();
+ cmGlobalGenerator* globalGen = makefile->GetGlobalGenerator();
+ std::vector<std::string> includeDirs;
+ cmGeneratorTarget *gtgt = globalGen->GetGeneratorTarget(target);
+ cmLocalGenerator *localGen = gtgt->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, gtgt, "CXX", config, false);
+
+ incs = cmJoin(includeDirs, ";");
+
+ std::set<std::string> defines;
+ localGen->AddCompileDefinitions(defines, target, config, "CXX");
+
+ defs += cmJoin(defines, ";");
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
+ cmTarget const* target)
+{
+ cmMakefile* makefile = 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 =
+ cmQtAutoGeneratorInitializer::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 =
+ cmQtAutoGeneratorInitializer::GetAutogenTargetDir(target);
+
+ const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
+ if (!qtVersion)
+ {
+ qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
+ }
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ if (const char *targetQtVersion =
+ gtgt->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"))
+ {
+ cmQtAutoGeneratorInitializer::SetupSourceFiles(target, skipMoc,
+ mocSources, mocHeaders, skipUic);
+ }
+ makefile->AddDefinition("_cpp_files",
+ cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ cmQtAutoGeneratorInitializer::SetupAutoMocTarget(target, autogenTargetName,
+ skipMoc, mocHeaders,
+ configIncludes, configDefines);
+ }
+ if (target->GetPropertyAsBool("AUTOUIC"))
+ {
+ cmQtAutoGeneratorInitializer::SetupAutoUicTarget(target, skipUic,
+ configUicOptions);
+ }
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ cmQtAutoGeneratorInitializer::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";
+ }
+ }
+ }
+}
+
+void cmQtAutoGeneratorInitializer::SetupSourceFiles(cmTarget 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->GetMakefile();
+
+ std::vector<cmSourceFile*> srcFiles;
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ gtgt->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<cmTarget*>(target)->AddSource(*fileIt);
+ }
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoMocTarget(cmTarget 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)
+{
+ cmMakefile* makefile = 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)
+ {
+ cmTarget *qt5Moc = makefile->FindTargetToUse("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)
+ {
+ cmTarget *qt4Moc = makefile->FindTargetToUse("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(cmTarget const* target, const std::string& config,
+ std::string &optString)
+{
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ std::vector<std::string> opts;
+ gtgt->GetAutoUicOptions(opts, config);
+ optString = cmJoin(opts, ";");
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoUicTarget(cmTarget const* target,
+ std::vector<std::string> const& skipUic,
+ std::map<std::string, std::string> &configUicOptions)
+{
+ cmMakefile *makefile = 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)
+ {
+ cmTarget *qt5Uic = makefile->FindTargetToUse("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)
+ {
+ cmTarget *qt4Uic = makefile->FindTargetToUse("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());
+ }
+}
+
+void cmQtAutoGeneratorInitializer::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());
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoRccTarget(cmTarget const* target)
+{
+ std::string _rcc_files;
+ const char* sepRccFiles = "";
+ cmMakefile *makefile = target->GetMakefile();
+
+ std::vector<cmSourceFile*> srcFiles;
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ gtgt->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);
+ cmQtAutoGeneratorInitializer::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 = cmQtAutoGeneratorInitializer::ListQt5RccInputs(sf,
+ target,
+ depends);
+ }
+ else
+ {
+ entriesList =
+ cmQtAutoGeneratorInitializer::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",
+ cmQtAutoGeneratorInitializer::GetRccExecutable(target).c_str());
+}
+
+std::string cmQtAutoGeneratorInitializer::GetRccExecutable(
+ cmTarget const* target)
+{
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ cmMakefile *makefile = 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 =
+ gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
+ {
+ qtVersion = targetQtVersion;
+ }
+ }
+
+ std::string targetName = target->GetName();
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmTarget *qt5Rcc = makefile->FindTargetToUse("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)
+ {
+ cmTarget *qt4Rcc = makefile->FindTargetToUse("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();
+}
diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h
new file mode 100644
index 0000000..c22f172
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.h
@@ -0,0 +1,67 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ 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.
+============================================================================*/
+
+#ifndef cmQtAutoGeneratorInitializer_h
+#define cmQtAutoGeneratorInitializer_h
+
+#include "cmStandardIncludes.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+class cmSourceFile;
+class cmTarget;
+class cmLocalGenerator;
+
+class cmQtAutoGeneratorInitializer
+{
+public:
+ static void InitializeAutogenSources(cmTarget* target);
+ static void InitializeAutogenTarget(cmLocalGenerator* lg, cmTarget* target);
+ static void SetupAutoGenerateTarget(cmTarget const* target);
+
+ static std::string GetAutogenTargetName(cmTarget const* target);
+ static std::string GetAutogenTargetDir(cmTarget const* target);
+
+private:
+ static void SetupSourceFiles(cmTarget const* target,
+ std::vector<std::string>& skipMoc,
+ std::vector<std::string>& mocSources,
+ std::vector<std::string>& mocHeaders,
+ std::vector<std::string>& skipUic);
+
+ static void SetupAutoMocTarget(cmTarget const* target,
+ const std::string &autogenTargetName,
+ const std::vector<std::string>& skipMoc,
+ const std::vector<std::string>& mocHeaders,
+ std::map<std::string, std::string> &configIncludes,
+ std::map<std::string, std::string> &configDefines);
+ static void SetupAutoUicTarget(cmTarget const* target,
+ const std::vector<std::string>& skipUic,
+ std::map<std::string, std::string> &configUicOptions);
+ static void SetupAutoRccTarget(cmTarget const* target);
+
+ static void MergeRccOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts, bool isQt5);
+
+ static std::string GetRccExecutable(cmTarget const* target);
+
+ static std::string ListQt5RccInputs(cmSourceFile* sf, cmTarget const* target,
+ std::vector<std::string>& depends);
+
+ static std::string ListQt4RccInputs(cmSourceFile* sf,
+ std::vector<std::string>& depends);
+};
+
+#endif
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index becfeba..bbeb3dc 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -12,17 +12,12 @@
============================================================================*/
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmMakefile.h"
-#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmState.h"
#include "cmAlgorithms.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# include "cmGlobalVisualStudioGenerator.h"
-#endif
-
#include <sys/stat.h>
#include <cmsys/Terminal.h>
@@ -36,7 +31,6 @@
#include "cmQtAutoGenerators.h"
-
static bool requiresMocing(const std::string& text, std::string &macroName)
{
// this simple check is much much faster than the regexp
@@ -105,28 +99,6 @@ static std::string extractSubDir(const std::string& absPath,
return subDir;
}
-
-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 ReadAll(const std::string& filename)
-{
- cmsys::ifstream file(filename.c_str());
- std::stringstream stream;
- stream << file.rdbuf();
- file.close();
- return stream.str();
-}
-
cmQtAutoGenerators::cmQtAutoGenerators()
:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
,ColorOutput(true)
@@ -151,692 +123,6 @@ cmQtAutoGenerators::cmQtAutoGenerators()
}
}
-static std::string getAutogenTargetName(cmTarget const* target)
-{
- std::string autogenTargetName = target->GetName();
- autogenTargetName += "_automoc";
- return autogenTargetName;
-}
-
-static std::string getAutogenTargetDir(cmTarget const* target)
-{
- cmMakefile* makefile = target->GetMakefile();
- std::string targetDir = makefile->GetCurrentBinaryDirectory();
- targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
- targetDir += "/";
- targetDir += getAutogenTargetName(target);
- targetDir += ".dir/";
- return targetDir;
-}
-
-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;
-}
-
-std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf,
- cmTarget const* target,
- std::vector<std::string>& depends)
-{
- std::string rccCommand = this->GetRccExecutable(target);
- std::vector<std::string> qrcEntries;
-
- std::vector<std::string> command;
- command.push_back(rccCommand);
- command.push_back("-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@");
-}
-
-std::string cmQtAutoGenerators::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;
-}
-
-bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg,
- cmTarget* target)
-{
- cmMakefile* makefile = target->GetMakefile();
- // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
- std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
- if (qtMajorVersion == "")
- {
- qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
- }
- if (qtMajorVersion != "4" && qtMajorVersion != "5")
- {
- return false;
- }
-
- 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);
- }
- // 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;
- cmGeneratorTarget* gtgt =
- lg->GetGlobalGenerator()->GetGeneratorTarget(target);
- gtgt->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")
- {
- this->ListQt5RccInputs(sf, target, depends);
- }
- else
- {
- this->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->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);
- makefile->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(autogenTarget, target, "FOLDER");
- }
-
- target->AddUtility(autogenTargetName);
- }
-
- return true;
-}
-
-static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
- const std::string& config,
- std::string &incs,
- std::string &defs)
-{
- cmMakefile* makefile = target->GetMakefile();
- cmGlobalGenerator* globalGen = makefile->GetGlobalGenerator();
- std::vector<std::string> includeDirs;
- cmGeneratorTarget *gtgt = globalGen->GetGeneratorTarget(target);
- cmLocalGenerator *localGen = gtgt->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, gtgt, "CXX", config, false);
-
- incs = cmJoin(includeDirs, ";");
-
- std::set<std::string> defines;
- localGen->AddCompileDefinitions(defines, target, config, "CXX");
-
- defs += cmJoin(defines, ";");
-}
-
-void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
-{
- cmMakefile* makefile = 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");
- }
- cmGeneratorTarget *gtgt = target->GetMakefile()
- ->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
- if (const char *targetQtVersion =
- gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
- {
- qtVersion = targetQtVersion;
- }
- if (qtVersion)
- {
- makefile->AddDefinition("_target_qt_version", qtVersion);
- }
-
- 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"))
- {
- this->SetupSourceFiles(target);
- }
- makefile->AddDefinition("_cpp_files",
- cmOutputConverter::EscapeForCMake(this->Sources).c_str());
- if (target->GetPropertyAsBool("AUTOMOC"))
- {
- this->SetupAutoMocTarget(target, autogenTargetName,
- configIncludes, configDefines);
- }
- if (target->GetPropertyAsBool("AUTOUIC"))
- {
- this->SetupAutoUicTarget(target, configUicOptions);
- }
- if (target->GetPropertyAsBool("AUTORCC"))
- {
- this->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";
- }
- }
- }
-}
-
-void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
-{
- cmMakefile* makefile = target->GetMakefile();
-
- const char* sepFiles = "";
- const char* sepHeaders = "";
-
- std::vector<cmSourceFile*> srcFiles;
- cmGeneratorTarget *gtgt = target->GetMakefile()
- ->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
- gtgt->GetConfigCommonSourceFiles(srcFiles);
-
- const char *skipMocSep = "";
- const char *skipUicSep = "";
-
- 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 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 (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 (skipMoc)
- {
- this->SkipMoc += skipMocSep;
- this->SkipMoc += absFile;
- skipMocSep = ";";
- }
- else
- {
- cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
- ext.c_str());
- if (fileType == cmSystemTools::CXX_FILE_FORMAT)
- {
- this->Sources += sepFiles;
- this->Sources += absFile;
- sepFiles = ";";
- }
- else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
- {
- this->Headers += sepHeaders;
- this->Headers += absFile;
- sepHeaders = ";";
- }
- }
- }
- }
-
- for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
- fileIt != newRccFiles.end();
- ++fileIt)
- {
- const_cast<cmTarget*>(target)->AddSource(*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",
- cmOutputConverter::EscapeForCMake(_moc_options).c_str());
- makefile->AddDefinition("_skip_moc",
- cmOutputConverter::EscapeForCMake(this->SkipMoc).c_str());
- makefile->AddDefinition("_moc_headers",
- cmOutputConverter::EscapeForCMake(this->Headers).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)
- {
- cmTarget *qt5Moc = makefile->FindTargetToUse("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)
- {
- cmTarget *qt4Moc = makefile->FindTargetToUse("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());
- }
-}
-
void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
const std::vector<std::string> &fileOpts,
bool isQt5)
@@ -882,332 +168,6 @@ void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
}
-static void GetUicOpts(cmTarget const* target, const std::string& config,
- std::string &optString)
-{
- cmGeneratorTarget *gtgt = target->GetMakefile()
- ->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
- std::vector<std::string> opts;
- gtgt->GetAutoUicOptions(opts, config);
- optString = cmJoin(opts, ";");
-}
-
-void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
- std::map<std::string, std::string> &configUicOptions)
-{
- cmMakefile *makefile = target->GetMakefile();
-
- std::set<std::string> skipped;
- std::vector<std::string> skipVec;
- cmSystemTools::ExpandListArgument(this->SkipUic, skipVec);
- skipped.insert(skipVec.begin(), skipVec.end());
-
- makefile->AddDefinition("_skip_uic",
- cmOutputConverter::EscapeForCMake(this->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)
- {
- cmTarget *qt5Uic = makefile->FindTargetToUse("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)
- {
- cmTarget *qt4Uic = makefile->FindTargetToUse("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());
- }
-}
-
-void cmQtAutoGenerators::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());
-}
-
-void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
-{
- std::string _rcc_files;
- const char* sepRccFiles = "";
- cmMakefile *makefile = target->GetMakefile();
-
- std::vector<cmSourceFile*> srcFiles;
- cmGeneratorTarget *gtgt = target->GetMakefile()
- ->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
- gtgt->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);
- this->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 = this->ListQt5RccInputs(sf, target, depends);
- }
- else
- {
- entriesList = this->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",
- this->GetRccExecutable(target).c_str());
-}
-
-std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
-{
- cmGeneratorTarget *gtgt = target->GetMakefile()
- ->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
- cmMakefile *makefile = 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 =
- gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
- {
- qtVersion = targetQtVersion;
- }
- }
-
- std::string targetName = target->GetName();
- if (strcmp(qtVersion, "5") == 0)
- {
- cmTarget *qt5Rcc = makefile->FindTargetToUse("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)
- {
- cmTarget *qt4Rcc = makefile->FindTargetToUse("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();
-}
-
bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
const std::string& config)
{
@@ -1219,19 +179,18 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, snapshot));
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
- lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory);
- lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory);
- gg.SetCurrentMakefile(lg->GetMakefile());
+ mf->SetCurrentBinaryDirectory(targetDirectory);
+ mf->SetCurrentSourceDirectory(targetDirectory);
+ gg.SetCurrentMakefile(mf.get());
- this->ReadAutogenInfoFile(lg->GetMakefile(), targetDirectory, config);
- this->ReadOldMocDefinitionsFile(lg->GetMakefile(), targetDirectory);
+ this->ReadAutogenInfoFile(mf.get(), targetDirectory, config);
+ this->ReadOldMocDefinitionsFile(mf.get(), targetDirectory);
this->Init();
if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
{
- success = this->RunAutogen(lg->GetMakefile());
+ success = this->RunAutogen(mf.get());
}
this->WriteOldMocDefinitionsFile(targetDirectory);
@@ -1533,6 +492,14 @@ void cmQtAutoGenerators::Init()
}
+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();
+}
bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
{
@@ -2251,7 +1218,8 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
{
std::vector<std::string> fileOpts;
cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
- this->MergeUicOptions(opts, fileOpts, this->QtMajorVersion == "5");
+ cmQtAutoGenerators::MergeUicOptions(opts, fileOpts,
+ this->QtMajorVersion == "5");
}
command.insert(command.end(), opts.begin(), opts.end());
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 4f03348..ab7b6ed 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -15,10 +15,11 @@
#define cmQtAutoGenerators_h
#include <list>
+#include <vector>
+#include <string>
+#include <map>
-class cmGlobalGenerator;
class cmMakefile;
-class cmLocalGenerator;
class cmQtAutoGenerators
{
@@ -26,18 +27,7 @@ public:
cmQtAutoGenerators();
bool Run(const std::string& targetDirectory, const std::string& config);
- bool InitializeAutogenTarget(cmLocalGenerator* lg, cmTarget* target);
- void SetupAutoGenerateTarget(cmTarget const* target);
- void SetupSourceFiles(cmTarget const* target);
-
private:
- void SetupAutoMocTarget(cmTarget const* target,
- const std::string &autogenTargetName,
- std::map<std::string, std::string> &configIncludes,
- std::map<std::string, std::string> &configDefines);
- void SetupAutoUicTarget(cmTarget const* target,
- std::map<std::string, std::string> &configUicOptions);
- void SetupAutoRccTarget(cmTarget const* target);
bool ReadAutogenInfoFile(cmMakefile* makefile,
const std::string& targetDirectory,
@@ -83,20 +73,9 @@ private:
bool EndsWith(const std::string& str, const std::string& with);
bool StartsWith(const std::string& str, const std::string& with);
- void MergeUicOptions(std::vector<std::string> &opts,
- const std::vector<std::string> &fileOpts, bool isQt5);
-
- void MergeRccOptions(std::vector<std::string> &opts,
+ static void MergeUicOptions(std::vector<std::string> &opts,
const std::vector<std::string> &fileOpts, bool isQt5);
- std::string GetRccExecutable(cmTarget const* target);
-
- std::string ListQt5RccInputs(cmSourceFile* sf, cmTarget const* target,
- std::vector<std::string>& depends);
-
- std::string ListQt4RccInputs(cmSourceFile* sf,
- std::vector<std::string>& depends);
-
bool InputFilesNewerThanQrc(const std::string& qrcFile,
const std::string& rccOutput);