summaryrefslogtreecommitdiffstats
path: root/Source/cmQtAutoGeneratorInitializer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmQtAutoGeneratorInitializer.cxx')
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx522
1 files changed, 267 insertions, 255 deletions
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 5246a67..6d4c302 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -4,7 +4,7 @@
#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
-#include "cmFilePathUuid.h"
+#include "cmFilePathChecksum.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -26,7 +26,6 @@
#include <cmConfigure.h>
#include <cmsys/FStream.hxx>
#include <cmsys/RegularExpression.hxx>
-#include <iostream>
#include <map>
#include <set>
#include <sstream>
@@ -36,14 +35,34 @@
#include <utility>
#include <vector>
+static void utilCopyTargetProperty(cmTarget* destinationTarget,
+ cmTarget* sourceTarget,
+ const std::string& propertyName)
+{
+ const char* propertyValue = sourceTarget->GetProperty(propertyName);
+ if (propertyValue) {
+ destinationTarget->SetProperty(propertyName, propertyValue);
+ }
+}
+
+static std::string utilStripCR(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 GetAutogenTargetName(cmGeneratorTarget const* target)
{
std::string autogenTargetName = target->GetName();
- autogenTargetName += "_automoc";
+ autogenTargetName += "_autogen";
return autogenTargetName;
}
-static std::string GetAutogenTargetDir(cmGeneratorTarget const* target)
+static std::string GetAutogenTargetFilesDir(cmGeneratorTarget const* target)
{
cmMakefile* makefile = target->Target->GetMakefile();
std::string targetDir = makefile->GetCurrentBinaryDirectory();
@@ -60,73 +79,87 @@ static std::string GetAutogenTargetBuildDir(cmGeneratorTarget const* target)
std::string targetDir = makefile->GetCurrentBinaryDirectory();
targetDir += "/";
targetDir += GetAutogenTargetName(target);
- targetDir += ".dir/";
+ targetDir += "/";
return targetDir;
}
+static std::string GetQtMajorVersion(cmGeneratorTarget const* target)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+ std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion.empty()) {
+ qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+ }
+ const char* targetQtVersion =
+ target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", "");
+ if (targetQtVersion != CM_NULLPTR) {
+ qtMajorVersion = targetQtVersion;
+ }
+ return qtMajorVersion;
+}
+
static 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)
+ std::vector<std::string>& mocUicSources,
+ std::vector<std::string>& mocUicHeaders,
+ std::vector<std::string>& skipMocList,
+ std::vector<std::string>& skipUicList)
{
cmMakefile* makefile = target->Target->GetMakefile();
std::vector<cmSourceFile*> srcFiles;
target->GetConfigCommonSourceFiles(srcFiles);
- std::vector<std::string> newRccFiles;
+ const bool targetMoc = target->GetPropertyAsBool("AUTOMOC");
+ const bool targetUic = target->GetPropertyAsBool("AUTOUIC");
- cmFilePathUuid fpathUuid(makefile);
+ cmFilePathChecksum fpathCheckSum(makefile);
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"));
+ const cmSystemTools::FileFormat fileType =
+ cmSystemTools::GetFileFormat(sf->GetExtension().c_str());
- if (cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"))) {
- skipUic.push_back(absFile);
+ if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) &&
+ !(fileType == cmSystemTools::HEADER_FILE_FORMAT)) {
+ continue;
}
-
- std::string ext = sf->GetExtension();
-
- if (target->GetPropertyAsBool("AUTORCC")) {
- if (ext == "qrc" &&
- !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) {
-
- std::string rcc_output_file = GetAutogenTargetBuildDir(target);
- // Create output directory
- cmSystemTools::MakeDirectory(rcc_output_file.c_str());
- rcc_output_file += fpathUuid.get(absFile, "qrc_", ".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 (cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
+ continue;
+ }
+ const std::string absFile =
+ cmsys::SystemTools::GetRealPath(sf->GetFullPath());
+ // Skip flags
+ const bool skipAll =
+ cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN"));
+ const bool skipMoc =
+ skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+ const bool skipUic =
+ skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"));
+ // Add file name to skip lists.
+ // Do this even when the file is not added to the sources/headers lists
+ // because the file name may be extracted from an other file when
+ // processing
+ if (skipMoc) {
+ skipMocList.push_back(absFile);
+ }
+ if (skipUic) {
+ skipUicList.push_back(absFile);
}
- 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);
- }
+ if ((targetMoc && !skipMoc) || (targetUic && !skipUic)) {
+ // Add file name to sources or headers list
+ switch (fileType) {
+ case cmSystemTools::CXX_FILE_FORMAT:
+ mocUicSources.push_back(absFile);
+ break;
+ case cmSystemTools::HEADER_FILE_FORMAT:
+ mocUicHeaders.push_back(absFile);
+ break;
+ default:
+ break;
}
}
}
-
- for (std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
- fileIt != newRccFiles.end(); ++fileIt) {
- const_cast<cmGeneratorTarget*>(target)->AddSource(*fileIt);
- }
}
static void GetCompileDefinitionsAndDirectories(
@@ -147,10 +180,9 @@ static void GetCompileDefinitionsAndDirectories(
defs += cmJoin(defines, ";");
}
-static void SetupAutoMocTarget(
+static void MocSetupAutoTarget(
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)
{
@@ -164,9 +196,6 @@ static void SetupAutoMocTarget(
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");
@@ -230,7 +259,7 @@ static void SetupAutoMocTarget(
}
}
-static void GetUicOpts(cmGeneratorTarget const* target,
+static void UicGetOpts(cmGeneratorTarget const* target,
const std::string& config, std::string& optString)
{
std::vector<std::string> opts;
@@ -238,7 +267,7 @@ static void GetUicOpts(cmGeneratorTarget const* target,
optString = cmJoin(opts, ";");
}
-static void SetupAutoUicTarget(
+static void UicSetupAutoTarget(
cmGeneratorTarget const* target, std::vector<std::string> const& skipUic,
std::map<std::string, std::string>& configUicOptions)
{
@@ -260,7 +289,7 @@ static void SetupAutoUicTarget(
std::string _uic_opts;
std::vector<std::string> configs;
const std::string& config = makefile->GetConfigurations(configs);
- GetUicOpts(target, config, _uic_opts);
+ UicGetOpts(target, config, _uic_opts);
if (!_uic_opts.empty()) {
_uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);
@@ -269,7 +298,7 @@ static void SetupAutoUicTarget(
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);
+ UicGetOpts(target, *li, config_uic_opts);
if (config_uic_opts != _uic_opts) {
configUicOptions[*li] =
cmOutputConverter::EscapeForCMake(config_uic_opts);
@@ -332,25 +361,13 @@ static void SetupAutoUicTarget(
}
}
-static std::string GetRccExecutable(cmGeneratorTarget const* target)
+static std::string RccGetExecutable(cmGeneratorTarget const* target,
+ const std::string& qtMajorVersion)
{
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) {
+ std::string const& targetName = target->GetName();
+ if (qtMajorVersion == "5") {
cmGeneratorTarget* qt5Rcc = lg->FindGeneratorTargetToUse("Qt5::rcc");
if (!qt5Rcc) {
cmSystemTools::Error("Qt5::rcc target not found ", targetName.c_str());
@@ -358,7 +375,7 @@ static std::string GetRccExecutable(cmGeneratorTarget const* target)
}
return qt5Rcc->ImportedGetLocation("");
}
- if (strcmp(qtVersion, "4") == 0) {
+ if (qtMajorVersion == "4") {
cmGeneratorTarget* qt4Rcc = lg->FindGeneratorTargetToUse("Qt4::rcc");
if (!qt4Rcc) {
cmSystemTools::Error("Qt4::rcc target not found ", targetName.c_str());
@@ -373,7 +390,7 @@ static std::string GetRccExecutable(cmGeneratorTarget const* target)
return std::string();
}
-static void MergeRccOptions(std::vector<std::string>& opts,
+static void RccMergeOptions(std::vector<std::string>& opts,
const std::vector<std::string>& fileOpts,
bool isQt5)
{
@@ -405,41 +422,16 @@ static void MergeRccOptions(std::vector<std::string>& opts,
opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
}
-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::ostringstream stream;
- stream << file.rdbuf();
- file.close();
- return stream.str();
-}
-
/// @brief Reads the resource files list from from a .qrc file - Qt5 version
/// @return True if the .qrc file was successfully parsed
-static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
+static bool RccListInputsQt5(cmSourceFile* sf, cmGeneratorTarget const* target,
std::vector<std::string>& depends)
{
- std::string rccCommand = GetRccExecutable(target);
+ const std::string rccCommand = RccGetExecutable(target, "5");
+ if (rccCommand.empty()) {
+ cmSystemTools::Error("AUTOGEN: error: rcc executable not available\n");
+ return false;
+ }
bool hasDashDashList = false;
// Read rcc features
@@ -487,7 +479,7 @@ static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
std::istringstream ostr(rccStdOut);
std::string oline;
while (std::getline(ostr, oline)) {
- oline = cmQtAutoGeneratorsStripCR(oline);
+ oline = utilStripCR(oline);
if (!oline.empty()) {
depends.push_back(oline);
}
@@ -498,7 +490,7 @@ static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
std::istringstream estr(rccStdErr);
std::string eline;
while (std::getline(estr, eline)) {
- eline = cmQtAutoGeneratorsStripCR(eline);
+ eline = utilStripCR(eline);
if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
static std::string searchString = "Cannot find file '";
@@ -522,10 +514,16 @@ static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
/// @brief Reads the resource files list from from a .qrc file - Qt4 version
/// @return True if the .qrc file was successfully parsed
-static bool ListQt4RccInputs(cmSourceFile* sf,
+static bool RccListInputsQt4(cmSourceFile* sf,
std::vector<std::string>& depends)
{
- const std::string qrcContents = ReadAll(sf->GetFullPath());
+ // Read file into string
+ std::string qrcContents;
+ {
+ std::ostringstream stream;
+ stream << cmsys::ifstream(sf->GetFullPath().c_str()).rdbuf();
+ qrcContents = stream.str();
+ }
cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
@@ -552,17 +550,18 @@ static bool ListQt4RccInputs(cmSourceFile* sf,
/// @brief Reads the resource files list from from a .qrc file
/// @return True if the rcc file was successfully parsed
-static bool ListQtRccInputs(const std::string& qtMajorVersion,
- cmSourceFile* sf, cmGeneratorTarget const* target,
- std::vector<std::string>& depends)
+static bool RccListInputs(const std::string& qtMajorVersion, cmSourceFile* sf,
+ cmGeneratorTarget const* target,
+ std::vector<std::string>& depends)
{
if (qtMajorVersion == "5") {
- return ListQt5RccInputs(sf, target, depends);
+ return RccListInputsQt5(sf, target, depends);
}
- return ListQt4RccInputs(sf, depends);
+ return RccListInputsQt4(sf, depends);
}
-static void SetupAutoRccTarget(cmGeneratorTarget const* target)
+static void RccSetupAutoTarget(cmGeneratorTarget const* target,
+ const std::string& qtMajorVersion)
{
std::string _rcc_files;
const char* sepRccFiles = "";
@@ -578,16 +577,12 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
std::string rccFileOptions;
const char* optionSep = "";
- const char* qtVersion = makefile->GetDefinition("_target_qt_version");
+ const bool qtMajorVersion5 = (qtMajorVersion == "5");
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) {
@@ -595,7 +590,9 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
std::string ext = sf->GetExtension();
if (ext == "qrc") {
std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath());
- bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
+ const bool skip =
+ cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) ||
+ cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
if (!skip) {
_rcc_files += sepRccFiles;
@@ -605,7 +602,7 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) {
std::vector<std::string> optsVec;
cmSystemTools::ExpandListArgument(prop, optsVec);
- MergeRccOptions(rccOptions, optsVec, strcmp(qtVersion, "5") == 0);
+ RccMergeOptions(rccOptions, optsVec, qtMajorVersion5);
}
if (!rccOptions.empty()) {
@@ -625,7 +622,7 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
std::string entriesList;
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
std::vector<std::string> depends;
- if (ListQtRccInputs(qtMajorVersion, sf, target, depends)) {
+ if (RccListInputs(qtMajorVersion, sf, target, depends)) {
entriesList = cmJoin(depends, "@list_sep@");
} else {
return;
@@ -638,38 +635,28 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
}
}
makefile->AddDefinition(
- "_qt_rcc_inputs_" + target->GetName(),
- cmOutputConverter::EscapeForCMake(qrcInputs).c_str());
-
+ "_rcc_inputs", cmOutputConverter::EscapeForCMake(qrcInputs).c_str());
makefile->AddDefinition(
"_rcc_files", cmOutputConverter::EscapeForCMake(_rcc_files).c_str());
-
makefile->AddDefinition(
- "_qt_rcc_options_files",
+ "_rcc_options_files",
cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());
makefile->AddDefinition(
- "_qt_rcc_options_options",
+ "_rcc_options_options",
cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());
-
makefile->AddDefinition("_qt_rcc_executable",
- GetRccExecutable(target).c_str());
+ RccGetExecutable(target, qtMajorVersion).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);
-
+ cmMakefile* makefile = target->Target->GetMakefile();
+ const std::string mocCppFile =
+ GetAutogenTargetBuildDir(target) + "moc_compilation.cpp";
+ cmSourceFile* gf = makefile->GetOrCreateSource(mocCppFile, true);
+ gf->SetProperty("SKIP_AUTOGEN", "On");
target->AddSource(mocCppFile);
}
}
@@ -679,56 +666,77 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
{
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);
+ // Create a custom target for running generators at buildtime
+ const std::string autogenTargetName = GetAutogenTargetName(target);
+ const std::string autogenBuildDir = GetAutogenTargetBuildDir(target);
+ const std::string workingDirectory =
+ cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
+ const std::string qtMajorVersion = GetQtMajorVersion(target);
+ std::vector<std::string> autogenOutputFiles;
- cmCustomCommandLine currentLine;
- currentLine.push_back(cmSystemTools::GetCMakeCommand());
- currentLine.push_back("-E");
- currentLine.push_back("cmake_autogen");
- currentLine.push_back(targetDir);
- currentLine.push_back("$<CONFIGURATION>");
+ // Create autogen target build directory and add it to the clean files
+ cmSystemTools::MakeDirectory(autogenBuildDir);
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ autogenBuildDir.c_str(), false);
- cmCustomCommandLines commandLines;
- commandLines.push_back(currentLine);
+ if (target->GetPropertyAsBool("AUTOMOC") ||
+ target->GetPropertyAsBool("AUTOUIC")) {
+ // Create autogen target includes directory and
+ // add it to the origin target INCLUDE_DIRECTORIES
+ const std::string incsDir = autogenBuildDir + "include";
+ cmSystemTools::MakeDirectory(incsDir);
+ target->AddIncludeDirectory(incsDir, true);
+ }
- std::string workingDirectory =
- cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
+ if (target->GetPropertyAsBool("AUTOMOC")) {
+ // Register moc compilation file as generated
+ autogenOutputFiles.push_back(autogenBuildDir + "moc_compilation.cpp");
+ }
+ // Initialize autogen target dependencies
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");
+
+ // Compose command lines
+ cmCustomCommandLines commandLines;
+ {
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(cmSystemTools::GetCMakeCommand());
+ currentLine.push_back("-E");
+ currentLine.push_back("cmake_autogen");
+ currentLine.push_back(GetAutogenTargetFilesDir(target));
+ currentLine.push_back("$<CONFIGURATION>");
+ commandLines.push_back(currentLine);
}
- std::string tools = toolNames[0];
- toolNames.erase(toolNames.begin());
- while (toolNames.size() > 1) {
- tools += ", " + toolNames[0];
+ // Compose target comment
+ std::string autogenComment;
+ {
+ 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];
+ }
+ autogenComment = "Automatic " + tools + " for target " + target->GetName();
}
- 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;
@@ -742,6 +750,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// https://connect.microsoft.com/VisualStudio/feedback/details/769495
usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
if (usePRE_BUILD) {
+ // If the autogen target depends on an other target
+ // don't use PRE_BUILD
for (std::vector<std::string>::iterator it = depends.begin();
it != depends.end(); ++it) {
if (!makefile->FindTargetToUse(it->c_str())) {
@@ -753,35 +763,44 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
}
#endif
- std::vector<std::string> rcc_output;
- bool const isNinja = lg->GetGlobalGenerator()->GetName() == "Ninja";
- if (isNinja
-#if defined(_WIN32) && !defined(__CYGWIN__)
- || usePRE_BUILD
-#endif
- ) {
+ if (target->GetPropertyAsBool("AUTORCC")) {
+ cmFilePathChecksum fpathCheckSum(makefile);
std::vector<cmSourceFile*> srcFiles;
target->GetConfigCommonSourceFiles(srcFiles);
- cmFilePathUuid fpathUuid(makefile);
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 rcc_output_file = GetAutogenTargetBuildDir(target);
- // Create output directory
- cmSystemTools::MakeDirectory(rcc_output_file.c_str());
- rcc_output_file += fpathUuid.get(absFile, "qrc_", ".cpp");
- rcc_output.push_back(rcc_output_file);
- }
+ if (sf->GetExtension() == "qrc" &&
+ !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) &&
+ !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) {
+ {
+ const std::string absFile =
+ cmsys::SystemTools::GetRealPath(sf->GetFullPath());
+
+ // Run cmake again when .qrc file changes
+ makefile->AddCMakeDependFile(absFile);
+
+ std::string rccOutputFile = autogenBuildDir;
+ rccOutputFile += fpathCheckSum.getPart(absFile);
+ rccOutputFile += "/qrc_";
+ rccOutputFile +=
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+ rccOutputFile += ".cpp";
+
+ // Add rcc output file to origin target sources
+ cmSourceFile* gf = makefile->GetOrCreateSource(rccOutputFile, true);
+ gf->SetProperty("SKIP_AUTOGEN", "On");
+ target->AddSource(rccOutputFile);
+ // Register rcc output file as generated
+ autogenOutputFiles.push_back(rccOutputFile);
+ }
+ if (lg->GetGlobalGenerator()->GetName() == "Ninja"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ || usePRE_BUILD
+#endif
+ ) {
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- ListQtRccInputs(qtMajorVersion, sf, target, depends);
+ RccListInputs(qtMajorVersion, sf, target, 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
@@ -812,7 +831,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
{
cmTarget* autogenTarget = makefile->AddUtilityCommand(
autogenTargetName, true, workingDirectory.c_str(),
- /*byproducts=*/rcc_output, depends, commandLines, false,
+ /*byproducts=*/autogenOutputFiles, depends, commandLines, false,
autogenComment.c_str());
cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
@@ -829,7 +848,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
autogenTarget->SetProperty("FOLDER", autogenFolder);
} else {
// inherit FOLDER property from target (#13688)
- copyTargetProperty(gt->Target, target->Target, "FOLDER");
+ utilCopyTargetProperty(gt->Target, target->Target, "FOLDER");
}
target->Target->AddUtility(autogenTargetName);
@@ -846,7 +865,8 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
static_cast<void>(varScope);
// create a custom target for running generators at buildtime:
- std::string autogenTargetName = GetAutogenTargetName(target);
+ const std::string autogenTargetName = GetAutogenTargetName(target);
+ const std::string qtMajorVersion = GetQtMajorVersion(target);
makefile->AddDefinition(
"_moc_target_name",
@@ -854,72 +874,64 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
makefile->AddDefinition(
"_origin_target_name",
cmOutputConverter::EscapeForCMake(target->GetName()).c_str());
+ makefile->AddDefinition("_target_qt_version", qtMajorVersion.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> mocUicSources;
+ std::vector<std::string> mocUicHeaders;
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::vector<std::string> skipUic;
+ std::map<std::string, std::string> configMocIncludes;
+ std::map<std::string, std::string> configMocDefines;
std::map<std::string, std::string> configUicOptions;
if (target->GetPropertyAsBool("AUTOMOC") ||
target->GetPropertyAsBool("AUTOUIC") ||
target->GetPropertyAsBool("AUTORCC")) {
- SetupSourceFiles(target, skipMoc, mocSources, mocHeaders, skipUic);
+ SetupSourceFiles(target, mocUicSources, mocUicHeaders, skipMoc, skipUic);
}
makefile->AddDefinition(
- "_cpp_files",
- cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());
+ "_moc_uic_sources",
+ cmOutputConverter::EscapeForCMake(cmJoin(mocUicSources, ";")).c_str());
+ makefile->AddDefinition(
+ "_moc_uic_headers",
+ cmOutputConverter::EscapeForCMake(cmJoin(mocUicHeaders, ";")).c_str());
+
if (target->GetPropertyAsBool("AUTOMOC")) {
- SetupAutoMocTarget(target, autogenTargetName, skipMoc, mocHeaders,
- configIncludes, configDefines);
+ MocSetupAutoTarget(target, autogenTargetName, skipMoc, configMocIncludes,
+ configMocDefines);
}
if (target->GetPropertyAsBool("AUTOUIC")) {
- SetupAutoUicTarget(target, skipUic, configUicOptions);
+ UicSetupAutoTarget(target, skipUic, configUicOptions);
}
if (target->GetPropertyAsBool("AUTORCC")) {
- SetupAutoRccTarget(target);
+ RccSetupAutoTarget(target, qtMajorVersion);
}
+ // Generate config file
std::string inputFile = cmSystemTools::GetCMakeRoot();
inputFile += "/Modules/AutogenInfo.cmake.in";
- std::string outputFile = targetDir;
+ std::string outputFile = GetAutogenTargetFilesDir(target);
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;
+ // Append custom definitions to config file
+ if (!configMocDefines.empty() || !configMocIncludes.empty() ||
+ !configUicOptions.empty()) {
+
+ // 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;
+ mode_t mode_write = S_IWRITE;
#else
- mode_t mode_write = S_IWUSR;
+ 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()) {
+ cmSystemTools::GetPermissions(outputFile, perm);
+ if (!(perm & mode_write)) {
+ cmSystemTools::SetPermissions(outputFile, perm | mode_write);
+ }
+
cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);
if (!infoFile) {
std::string error = "Internal CMake error when trying to open file: ";
@@ -928,19 +940,19 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
cmSystemTools::Error(error.c_str());
return;
}
- if (!configDefines.empty()) {
+ if (!configMocDefines.empty()) {
for (std::map<std::string, std::string>::iterator
- it = configDefines.begin(),
- end = configDefines.end();
+ it = configMocDefines.begin(),
+ end = configMocDefines.end();
it != end; ++it) {
infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first << " "
<< it->second << ")\n";
}
}
- if (!configIncludes.empty()) {
+ if (!configMocIncludes.empty()) {
for (std::map<std::string, std::string>::iterator
- it = configIncludes.begin(),
- end = configIncludes.end();
+ it = configMocIncludes.begin(),
+ end = configMocIncludes.end();
it != end; ++it) {
infoFile << "set(AM_MOC_INCLUDES_" << it->first << " " << it->second
<< ")\n";