Merge topic 'autogen_strcat'

32b15d320f Autogen: cmQtAutoMocUic settings hash computation optimizations
b66cd3fe63 Autogen: cmQtAutoMocUic string concatenation cleanups
619a92eacd Autogen: cmQtAutoRcc settings hash computation optimizations
10dc684508 Autogen: cmQtAutoRcc string concatenation cleanups
da6c4b1273 Autogen: cmQtAutoGenInitializer string concatenation cleanups
7a78d15415 Autogen: Let cmQtAutoGenerator::Logger methods accept cm::string_view
c797148e85 Autogen: Use cm::string_view for AUTO{MOC,UIC,RCC} generator names
8586077baa Autogen: Modernize cmQtAutoGen methods using cm::string_view

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3742
This commit is contained in:
Brad King 2019-08-29 13:36:25 +00:00 committed by Kitware Robot
commit 030570d71f
9 changed files with 448 additions and 571 deletions

View File

@ -12,6 +12,7 @@
#include <algorithm>
#include <array>
#include <initializer_list>
#include <sstream>
#include <utility>
@ -21,7 +22,7 @@
/// @arg valueOpts list of options that accept a value
void MergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
std::vector<std::string> const& valueOpts, bool isQt5)
std::initializer_list<cm::string_view> valueOpts, bool isQt5)
{
typedef std::vector<std::string>::iterator Iter;
typedef std::vector<std::string>::const_iterator CIter;
@ -75,102 +76,74 @@ void MergeOptions(std::vector<std::string>& baseOpts,
unsigned int const cmQtAutoGen::ParallelMax = 64;
std::string const cmQtAutoGen::ListSep = "<<<S>>>";
std::string const& cmQtAutoGen::GeneratorName(GenT genType)
cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
static const std::string AutoGen("AutoGen");
static const std::string AutoMoc("AutoMoc");
static const std::string AutoUic("AutoUic");
static const std::string AutoRcc("AutoRcc");
switch (genType) {
case GenT::GEN:
return AutoGen;
return "AutoGen";
case GenT::MOC:
return AutoMoc;
return "AutoMoc";
case GenT::UIC:
return AutoUic;
return "AutoUic";
case GenT::RCC:
return AutoRcc;
return "AutoRcc";
}
return AutoGen;
return "AutoGen";
}
std::string const& cmQtAutoGen::GeneratorNameUpper(GenT genType)
cm::string_view cmQtAutoGen::GeneratorNameUpper(GenT genType)
{
static const std::string AUTOGEN("AUTOGEN");
static const std::string AUTOMOC("AUTOMOC");
static const std::string AUTOUIC("AUTOUIC");
static const std::string AUTORCC("AUTORCC");
switch (genType) {
case GenT::GEN:
return AUTOGEN;
return "AUTOGEN";
case GenT::MOC:
return AUTOMOC;
return "AUTOMOC";
case GenT::UIC:
return AUTOUIC;
return "AUTOUIC";
case GenT::RCC:
return AUTORCC;
return "AUTORCC";
}
return AUTOGEN;
return "AUTOGEN";
}
std::string cmQtAutoGen::Tools(bool moc, bool uic, bool rcc)
{
std::string res;
std::vector<std::string> lst;
std::array<cm::string_view, 3> lst;
decltype(lst)::size_type num = 0;
if (moc) {
lst.emplace_back("AUTOMOC");
lst.at(num++) = "AUTOMOC";
}
if (uic) {
lst.emplace_back("AUTOUIC");
lst.at(num++) = "AUTOUIC";
}
if (rcc) {
lst.emplace_back("AUTORCC");
lst.at(num++) = "AUTORCC";
}
switch (lst.size()) {
switch (num) {
case 1:
res += lst.at(0);
break;
return std::string(lst[0]);
case 2:
res += lst.at(0);
res += " and ";
res += lst.at(1);
break;
return cmStrCat(lst[0], " and ", lst[1]);
case 3:
res += lst.at(0);
res += ", ";
res += lst.at(1);
res += " and ";
res += lst.at(2);
break;
return cmStrCat(lst[0], ", ", lst[1], " and ", lst[2]);
default:
break;
}
return res;
return std::string();
}
std::string cmQtAutoGen::Quoted(std::string const& text)
std::string cmQtAutoGen::Quoted(cm::string_view text)
{
const std::array<std::pair<const char*, const char*>, 9> replaces = {
{ { "\\", "\\\\" },
{ "\"", "\\\"" },
{ "\a", "\\a" },
{ "\b", "\\b" },
{ "\f", "\\f" },
{ "\n", "\\n" },
{ "\r", "\\r" },
{ "\t", "\\t" },
{ "\v", "\\v" } }
};
static std::initializer_list<std::pair<const char*, const char*>> const
replacements = { { "\\", "\\\\" }, { "\"", "\\\"" }, { "\a", "\\a" },
{ "\b", "\\b" }, { "\f", "\\f" }, { "\n", "\\n" },
{ "\r", "\\r" }, { "\t", "\\t" }, { "\v", "\\v" } };
std::string res = text;
for (auto const& pair : replaces) {
std::string res(text);
for (auto const& pair : replacements) {
cmSystemTools::ReplaceString(res, pair.first, pair.second);
}
res = '"' + res;
res += '"';
return res;
return cmStrCat('"', res, '"');
}
std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
@ -191,37 +164,31 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
return res;
}
std::string cmQtAutoGen::SubDirPrefix(std::string const& filename)
std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename)
{
std::string::size_type slash_pos = filename.rfind('/');
if (slash_pos == std::string::npos) {
auto slashPos = filename.rfind('/');
if (slashPos == cm::string_view::npos) {
return std::string();
}
return filename.substr(0, slash_pos + 1);
return std::string(filename.substr(0, slashPos + 1));
}
std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename,
std::string const& suffix)
std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename,
cm::string_view suffix)
{
std::string res;
auto pos = filename.rfind('.');
if (pos != std::string::npos) {
const auto it_dot = filename.begin() + pos;
res.assign(filename.begin(), it_dot);
res.append(suffix);
res.append(it_dot, filename.end());
} else {
res = filename;
res.append(suffix);
auto dotPos = filename.rfind('.');
if (dotPos == cm::string_view::npos) {
return cmStrCat(filename, suffix);
}
return res;
return cmStrCat(filename.substr(0, dotPos), suffix,
filename.substr(dotPos, filename.size() - dotPos));
}
void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
static std::vector<std::string> const valueOpts = {
static std::initializer_list<cm::string_view> const valueOpts = {
"tr", "translate", "postfix", "generator",
"include", // Since Qt 5.3
"g"
@ -233,9 +200,9 @@ void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
static std::vector<std::string> const valueOpts = { "name", "root",
"compress",
"threshold" };
static std::initializer_list<cm::string_view> const valueOpts = {
"name", "root", "compress", "threshold"
};
MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
}
@ -349,9 +316,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
// Log command
if (verbose) {
std::string msg =
cmStrCat("Running command:\n", QuotedCommand(cmd), '\n');
cmSystemTools::Stdout(msg);
cmSystemTools::Stdout(
cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'));
}
result = cmSystemTools::RunSingleCommand(
@ -362,12 +328,10 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
error =
cmStrCat("The rcc list process failed for ", Quoted(qrcFile), '\n');
if (!rccStdOut.empty()) {
error += rccStdOut;
error += "\n";
error += cmStrCat(rccStdOut, '\n');
}
if (!rccStdErr.empty()) {
error += rccStdErr;
error += "\n";
error += cmStrCat(rccStdErr, '\n');
}
return false;
}

View File

@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cm_string_view.hxx"
#include <memory>
#include <string>
#include <vector>
@ -66,24 +68,24 @@ public:
public:
/// @brief Returns the generator name
static std::string const& GeneratorName(GenT genType);
static cm::string_view GeneratorName(GenT genType);
/// @brief Returns the generator name in upper case
static std::string const& GeneratorNameUpper(GenT genType);
static cm::string_view GeneratorNameUpper(GenT genType);
/// @brief Returns a string with the requested tool names
static std::string Tools(bool moc, bool uic, bool rcc);
/// @brief Returns the string escaped and enclosed in quotes
static std::string Quoted(std::string const& text);
static std::string Quoted(cm::string_view text);
static std::string QuotedCommand(std::vector<std::string> const& command);
/// @brief Returns the parent directory of the file with a "/" suffix
static std::string SubDirPrefix(std::string const& filename);
static std::string SubDirPrefix(cm::string_view filename);
/// @brief Appends the suffix to the filename before the last dot
static std::string AppendFilenameSuffix(std::string const& filename,
std::string const& suffix);
static std::string AppendFilenameSuffix(cm::string_view filename,
cm::string_view suffix);
/// @brief Merges newOpts into baseOpts
static void UicMergeOptions(std::vector<std::string>& baseOpts,

View File

@ -29,8 +29,8 @@
#include "cmsys/SystemInformation.hxx"
#include <algorithm>
#include <array>
#include <deque>
#include <initializer_list>
#include <map>
#include <set>
#include <string>
@ -396,13 +396,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// CMAKE_AUTOMOC_RELAXED_MODE deprecation warning
if (this->Moc.Enabled) {
if (cmIsOn(makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) {
std::string msg =
if (makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
"deprecated an will be removed in the future. Consider "
"disabling it and converting the target ",
this->Target->GetName(), " to regular mode.");
makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
this->Target->GetName(), " to regular mode."));
}
}
}
@ -696,7 +696,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::vector<MUFileHandle> extraHeaders;
extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2);
// Header search suffixes and extensions
std::array<std::string, 2> const suffixes{ { "", "_p" } };
static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
auto const& exts = cm->GetHeaderExtensions();
// Scan through sources
for (auto const& pair : this->AutogenTarget.Sources) {
@ -708,7 +708,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath),
cmSystemTools::GetFilenameWithoutLastExtension(srcPath));
for (auto const& suffix : suffixes) {
std::string const suffixedPath = basePath + suffix;
std::string const suffixedPath = cmStrCat(basePath, suffix);
for (auto const& ext : exts) {
std::string fullPath = cmStrCat(suffixedPath, '.', ext);
@ -814,33 +814,31 @@ bool cmQtAutoGenInitializer::InitScanFiles()
this->AutogenTarget.DependFiles.insert(muf->RealPath);
}
} else if (this->CMP0071Warn) {
std::string msg =
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n');
std::string property;
cm::string_view property;
if (this->Moc.Enabled && this->Uic.Enabled) {
property = kw.SKIP_AUTOGEN;
property = "SKIP_AUTOGEN";
} else if (this->Moc.Enabled) {
property = kw.SKIP_AUTOMOC;
property = "SKIP_AUTOMOC";
} else if (this->Uic.Enabled) {
property = kw.SKIP_AUTOUIC;
property = "SKIP_AUTOUIC";
}
msg += "For compatibility, CMake is excluding the GENERATED source "
"file(s):\n";
std::string files;
for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
msg += " ";
msg += Quoted(muf->RealPath);
msg += '\n';
files += cmStrCat(" ", Quoted(muf->RealPath), '\n');
}
msg += "from processing by ";
msg += cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false);
msg += ". If any of the files should be processed, set CMP0071 to NEW. "
"If any of the files should not be processed, "
"explicitly exclude them by setting the source file property ";
msg += property;
msg += ":\n set_property(SOURCE file.h PROPERTY ";
msg += property;
msg += " ON)\n";
makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n',
"For compatibility, CMake is excluding the GENERATED source "
"file(s):\n",
files, "from processing by ",
cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
". If any of the files should be processed, set CMP0071 to NEW. "
"If any of the files should not be processed, "
"explicitly exclude them by setting the source file property ",
property, ":\n set_property(SOURCE file.h PROPERTY ", property,
" ON)\n"));
}
}
@ -867,20 +865,16 @@ bool cmQtAutoGenInitializer::InitScanFiles()
for (Qrc& qrc : this->Rcc.Qrcs) {
qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
// RCC output file name
qrc.RccFile = cmStrCat(this->Dir.Build + "/", qrc.PathChecksum,
"/qrc_", qrc.QrcName, ".cpp");
qrc.RccFile = cmStrCat(this->Dir.Build, '/', qrc.PathChecksum, "/qrc_",
qrc.QrcName, ".cpp");
{
std::string base = cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName);
if (!qrc.Unique) {
base += qrc.PathChecksum;
}
cm::string_view const baseSuffix =
qrc.Unique ? cm::string_view() : cm::string_view(qrc.PathChecksum);
std::string const base =
cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName, baseSuffix);
qrc.LockFile = cmStrCat(base, ".lock");
qrc.InfoFile = cmStrCat(base, "Info.cmake");
qrc.SettingsFile = cmStrCat(base, "Settings.txt");
if (this->MultiConfig) {
for (std::string const& cfg : this->ConfigsList) {
qrc.ConfigSettingsFile[cfg] =
@ -900,7 +894,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Replace '-' with '_'. The former is not valid for symbol names.
std::replace(name.begin(), name.end(), '-', '_');
if (!qrc.Unique) {
name += cmStrCat("_", qrc.PathChecksum);
name += cmStrCat('_', qrc.PathChecksum);
}
std::vector<std::string> nameOpts;
nameOpts.emplace_back("-name");
@ -1131,8 +1125,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
{
ccName = cmStrCat(this->Target->GetName(), "_arcc_", qrc.QrcName);
if (!qrc.Unique) {
ccName += "_";
ccName += qrc.PathChecksum;
ccName += cmStrCat('_', qrc.PathChecksum);
}
cmTarget* autoRccTarget = makefile->AddUtilityCommand(
@ -1274,7 +1267,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
if (muf->MocIt || muf->UicIt) {
headers.emplace_back(muf->RealPath);
headersFlags.emplace_back(
cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
}
}
}
@ -1283,19 +1276,17 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
cmFilePathChecksum const fpathCheckSum(makefile);
std::unordered_set<std::string> emitted;
for (std::string const& hdr : headers) {
std::string basePath =
std::string const basePath =
cmStrCat(fpathCheckSum.getPart(hdr), "/moc_",
cmSystemTools::GetFilenameWithoutLastExtension(hdr));
for (int ii = 1; ii != 1024; ++ii) {
std::string path = basePath;
if (ii > 1) {
path += cmStrCat("_", ii);
}
path += ".cpp";
std::string suffix;
for (int ii = 0; ii != 1024; ++ii) {
std::string path = cmStrCat(basePath, suffix, ".cpp");
if (emitted.emplace(path).second) {
headersBuildPaths.emplace_back(std::move(path));
break;
}
suffix = cmStrCat('_', ii + 1);
}
}
}
@ -1329,7 +1320,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
if (muf->MocIt || muf->UicIt) {
sources.emplace_back(muf->RealPath);
sourcesFlags.emplace_back(
cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
}
}
}
@ -1454,7 +1445,7 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
}
bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
std::string const& genNameUpper)
cm::string_view genNameUpper)
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
cmSourceGroup* sourceGroup = nullptr;
@ -1464,13 +1455,14 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
std::string groupName;
{
// Prefer generator specific source group name
std::array<std::string, 2> props{ { genNameUpper + "_SOURCE_GROUP",
"AUTOGEN_SOURCE_GROUP" } };
for (std::string& prop : props) {
std::initializer_list<std::string> const props{
cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
};
for (std::string const& prop : props) {
const char* propName = makefile->GetState()->GetGlobalProperty(prop);
if ((propName != nullptr) && (*propName != '\0')) {
groupName = propName;
property = std::move(prop);
property = prop;
break;
}
}
@ -1512,11 +1504,16 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
cmGeneratorTarget const* target)
{
// Qt version variable prefixes
static std::array<std::string, 3> const prefixes{ { "Qt6Core", "Qt5Core",
"QT" } };
static std::initializer_list<
std::pair<cm::string_view, cm::string_view>> const keys{
{ "Qt6Core_VERSION_MAJOR", "Qt6Core_VERSION_MINOR" },
{ "Qt5Core_VERSION_MAJOR", "Qt5Core_VERSION_MINOR" },
{ "QT_VERSION_MAJOR", "QT_VERSION_MINOR" },
};
std::vector<cmQtAutoGen::IntegerVersion> result;
result.reserve(prefixes.size() * 2);
result.reserve(keys.size() * 2);
// Adds a version to the result (nullptr safe)
auto addVersion = [&result](const char* major, const char* minor) {
cmQtAutoGen::IntegerVersion ver(CharPtrToUInt(major),
@ -1525,18 +1522,19 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
result.emplace_back(ver);
}
};
cmMakefile* makefile = target->Target->GetMakefile();
// Read versions from variables
for (const std::string& prefix : prefixes) {
addVersion(makefile->GetDefinition(prefix + "_VERSION_MAJOR"),
makefile->GetDefinition(prefix + "_VERSION_MINOR"));
for (auto const& keyPair : keys) {
addVersion(makefile->GetDefinition(std::string(keyPair.first)),
makefile->GetDefinition(std::string(keyPair.second)));
}
// Read versions from directory properties
for (const std::string& prefix : prefixes) {
addVersion(makefile->GetProperty(prefix + "_VERSION_MAJOR"),
makefile->GetProperty(prefix + "_VERSION_MINOR"));
for (auto const& keyPair : keys) {
addVersion(makefile->GetProperty(std::string(keyPair.first)),
makefile->GetProperty(std::string(keyPair.second)));
}
return result;
@ -1580,7 +1578,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Custom executable
{
std::string const prop = genVars.GenNameUpper + "_EXECUTABLE";
std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
std::string const val = this->Target->Target->GetSafeProperty(prop);
if (!val.empty()) {
// Evaluate generator expression
@ -1607,15 +1605,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Find executable target
{
// Find executable target name
std::string targetName;
cm::string_view prefix;
if (this->QtVersion.Major == 4) {
targetName = "Qt4::";
prefix = "Qt4::";
} else if (this->QtVersion.Major == 5) {
targetName = "Qt5::";
prefix = "Qt5::";
} else if (this->QtVersion.Major == 6) {
targetName = "Qt6::";
prefix = "Qt6::";
}
targetName += executable;
std::string const targetName = cmStrCat(prefix, executable);
// Find target
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();

View File

@ -63,7 +63,7 @@ public:
bool Enabled = false;
// Generator type/name
GenT Gen;
std::string const& GenNameUpper;
cm::string_view GenNameUpper;
// Executable
std::string ExecutableTargetName;
cmGeneratorTarget* ExecutableTarget = nullptr;
@ -145,7 +145,7 @@ private:
bool AddGeneratedSource(std::string const& filename, GenVarsT const& genVars,
bool prepend = false);
bool AddToSourceGroup(std::string const& fileName,
std::string const& genNameUpper);
cm::string_view genNameUpper);
void AddCleanFile(std::string const& fileName);
bool GetQtExecutable(GenVarsT& genVars, const std::string& executable,

View File

@ -58,18 +58,16 @@ void cmQtAutoGenerator::Logger::SetColorOutput(bool value)
ColorOutput_ = value;
}
std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title)
std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title)
{
return cmStrCat(title, "\n", std::string(title.size(), '-'), "\n");
return cmStrCat(title, '\n', std::string(title.size(), '-'), '\n');
}
void cmQtAutoGenerator::Logger::Info(GenT genType,
std::string const& message) const
cm::string_view message) const
{
std::string msg = cmStrCat(GeneratorName(genType), ": ", message);
if (msg.back() != '\n') {
msg.push_back('\n');
}
std::string msg = cmStrCat(GeneratorName(genType), ": ", message,
cmHasSuffix(message, '\n') ? "" : "\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
@ -77,23 +75,18 @@ void cmQtAutoGenerator::Logger::Info(GenT genType,
}
void cmQtAutoGenerator::Logger::Warning(GenT genType,
std::string const& message) const
cm::string_view message) const
{
std::string msg;
if (message.find('\n') == std::string::npos) {
// Single line message
msg += GeneratorName(genType);
msg += " warning: ";
msg = cmStrCat(GeneratorName(genType), " warning: ", message,
cmHasSuffix(message, '\n') ? "\n" : "\n\n");
} else {
// Multi line message
msg += HeadLine(GeneratorName(genType) + " warning");
msg = cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " warning")),
message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
}
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
@ -101,22 +94,18 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType,
}
void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
std::string const& filename,
std::string const& message) const
cm::string_view filename,
cm::string_view message) const
{
Warning(genType, cmStrCat(" ", Quoted(filename), "\n", message));
Warning(genType, cmStrCat(" ", Quoted(filename), '\n', message));
}
void cmQtAutoGenerator::Logger::Error(GenT genType,
std::string const& message) const
cm::string_view message) const
{
std::string msg = HeadLine(GeneratorName(genType) + " error");
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
std::string msg =
cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " error")), message,
cmHasSuffix(message, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);
@ -124,36 +113,22 @@ void cmQtAutoGenerator::Logger::Error(GenT genType,
}
void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
std::string const& filename,
std::string const& message) const
cm::string_view filename,
cm::string_view message) const
{
Error(genType, cmStrCat(" ", Quoted(filename), '\n', message));
}
void cmQtAutoGenerator::Logger::ErrorCommand(
GenT genType, std::string const& message,
GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(GeneratorName(genType) + " subprocess error");
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
msg += HeadLine("Command");
msg += QuotedCommand(command);
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
msg += HeadLine("Output");
msg += output;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
std::string msg = cmStrCat(
'\n', HeadLine(cmStrCat(GeneratorName(genType), " subprocess error")),
message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
msg += cmStrCat(HeadLine("Command"), QuotedCommand(command), "\n\n");
msg += cmStrCat(HeadLine("Output"), output,
cmHasSuffix(output, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);

View File

@ -7,6 +7,7 @@
#include "cmFileTime.h"
#include "cmQtAutoGen.h"
#include "cm_string_view.hxx"
#include <mutex>
#include <string>
@ -41,21 +42,21 @@ public:
bool ColorOutput() const { return this->ColorOutput_; }
void SetColorOutput(bool value);
// -- Log info
void Info(GenT genType, std::string const& message) const;
void Info(GenT genType, cm::string_view message) const;
// -- Log warning
void Warning(GenT genType, std::string const& message) const;
void WarningFile(GenT genType, std::string const& filename,
std::string const& message) const;
void Warning(GenT genType, cm::string_view message) const;
void WarningFile(GenT genType, cm::string_view filename,
cm::string_view message) const;
// -- Log error
void Error(GenT genType, std::string const& message) const;
void ErrorFile(GenT genType, std::string const& filename,
std::string const& message) const;
void ErrorCommand(GenT genType, std::string const& message,
void Error(GenT genType, cm::string_view message) const;
void ErrorFile(GenT genType, cm::string_view filename,
cm::string_view message) const;
void ErrorCommand(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
private:
static std::string HeadLine(std::string const& title);
static std::string HeadLine(cm::string_view title);
private:
mutable std::mutex Mutex_;

View File

@ -3,10 +3,9 @@
#include "cmQtAutoMocUic.h"
#include <algorithm>
#include <array>
#include <initializer_list>
#include <list>
#include <set>
#include <sstream>
#include <utility>
#include "cm_memory.hxx"
@ -233,22 +232,21 @@ bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const
}
void cmQtAutoMocUic::JobT::LogError(GenT genType,
std::string const& message) const
cm::string_view message) const
{
Gen()->AbortError();
Gen()->Log().Error(genType, message);
}
void cmQtAutoMocUic::JobT::LogFileError(GenT genType,
std::string const& filename,
std::string const& message) const
void cmQtAutoMocUic::JobT::LogFileError(GenT genType, cm::string_view filename,
cm::string_view message) const
{
Gen()->AbortError();
Gen()->Log().ErrorFile(genType, filename, message);
}
void cmQtAutoMocUic::JobT::LogCommandError(
GenT genType, std::string const& message,
GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
Gen()->AbortError();
@ -262,16 +260,14 @@ bool cmQtAutoMocUic::JobT::RunProcess(GenT genType,
{
// Log command
if (Log().Verbose()) {
std::string msg;
if ((infoMessage != nullptr) && !infoMessage->empty()) {
msg = *infoMessage;
if (msg.back() != '\n') {
msg += '\n';
}
cm::string_view info;
if (infoMessage != nullptr) {
info = *infoMessage;
}
msg += QuotedCommand(command);
msg += '\n';
Log().Info(genType, msg);
Log().Info(genType,
cmStrCat(info,
info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
QuotedCommand(command), '\n'));
}
return cmWorkerPool::JobT::RunProcess(result, command,
BaseConst().AutogenBuildDir);
@ -302,10 +298,11 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
}
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
std::string msg =
cmStrCat("The content generation command for ",
Quoted(predefsFileRel), " failed.\n", result.ErrorMessage);
LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
LogCommandError(GenT::MOC,
cmStrCat("The content generation command for ",
Quoted(predefsFileRel), " failed.\n",
result.ErrorMessage),
cmd, result.StdOut);
return;
}
}
@ -313,9 +310,8 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
// (Re)write predefs file only on demand
if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
std::string msg =
cmStrCat("Writing ", Quoted(predefsFileRel), " failed.");
LogFileError(GenT::MOC, predefsFileAbs, msg);
LogFileError(GenT::MOC, predefsFileAbs,
cmStrCat("Writing ", Quoted(predefsFileRel), " failed."));
return;
}
} else {
@ -324,9 +320,9 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
}
if (!cmSystemTools::Touch(predefsFileAbs, false)) {
std::string msg =
cmStrCat("Touching ", Quoted(predefsFileAbs), " failed.");
LogFileError(GenT::MOC, predefsFileAbs, msg);
LogFileError(
GenT::MOC, predefsFileAbs,
cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."));
return;
}
}
@ -654,14 +650,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// Check if this source needs to be moc processed but doesn't.
if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
!(relaxedMode && sourceIncludesMocUnderscore)) {
{
std::string emsg =
cmStrCat("The file contains a ", Quoted(parseData.Macro),
" macro, but does not include ", Quoted(sourceBase + ".moc"),
"!\nConsider to\n - add #include \"", sourceBase,
".moc\"\n - enable SKIP_AUTOMOC for this file");
LogFileError(GenT::MOC, sourceFile.FileName, emsg);
}
LogFileError(GenT::MOC, sourceFile.FileName,
cmStrCat("The file contains a ", Quoted(parseData.Macro),
" macro, but does not include ",
Quoted(sourceBase + ".moc"),
"!\nConsider to\n - add #include \"", sourceBase,
".moc\"\n - enable SKIP_AUTOMOC for this file"));
return false;
}
@ -670,14 +664,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
std::string const headerBase = incKey.Dir + incKey.Base;
SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
if (!header) {
{
std::string msg =
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
",\nbut the header could not be found "
"in the following locations\n",
MocMessageTestHeaders(headerBase));
LogFileError(GenT::MOC, sourceFile.FileName, msg);
}
LogFileError(GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ",
Quoted(incKey.Key),
",\nbut the header could not be found "
"in the following locations\n",
MocMessageTestHeaders(headerBase)));
return false;
}
// The include might be handled differently in relaxed mode
@ -688,18 +680,19 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// be generated from <BASE>.cpp instead of <BASE>.h, because otherwise
// it won't build. But warn, since this is not how it is supposed to be
// used. This is for KDE4 compatibility.
{
// Issue a warning
std::string msg = cmStrCat(
"The file contains a ", Quoted(parseData.Macro),
" macro, but does not include ", Quoted(sourceBase + ".moc"),
".\nInstead it includes ", Quoted(incKey.Key),
".\nRunning moc on the source\n ", Quoted(sourceFile.FileName),
"!\nBetter include ", Quoted(sourceBase + ".moc"),
" for compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
}
// Issue a warning
Log().WarningFile(
GenT::MOC, sourceFile.FileName,
cmStrCat("The file contains a ", Quoted(parseData.Macro),
" macro, but does not include ", Quoted(sourceBase + ".moc"),
".\nInstead it includes ", Quoted(incKey.Key),
".\nRunning moc on the source\n ",
Quoted(sourceFile.FileName), "!\nBetter include ",
Quoted(sourceBase + ".moc"),
" for compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
return false;
@ -735,13 +728,13 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
std::string const headerBase = incKey.Dir + incKey.Base;
SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
if (!header) {
std::string msg =
LogFileError(
GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
",\nwhich seems to be the moc file from a different source "
"file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header"
"could not be found in the following locations\n",
MocMessageTestHeaders(headerBase));
LogFileError(GenT::MOC, sourceFile.FileName, msg);
MocMessageTestHeaders(headerBase)));
return false;
}
// Check if header is skipped
@ -750,23 +743,25 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
}
// Issue a warning
if (ownMoc && parseData.Macro.empty()) {
std::string msg = cmStrCat(
"The file includes the moc file ", Quoted(incKey.Key),
", but does not contain a\n", MocConst().MacrosString(),
" macro.\nRunning moc on the header\n ", Quoted(header->FileName),
"!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
" for a compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
Log().WarningFile(
GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
", but does not contain a\n", MocConst().MacrosString(),
" macro.\nRunning moc on the header\n ",
Quoted(header->FileName), "!\nBetter include ",
Quoted("moc_" + incKey.Base + ".cpp"),
" for a compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
} else {
std::string msg = cmStrCat(
"The file includes the moc file ", Quoted(incKey.Key),
" instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
".\nRunning moc on the header\n ", Quoted(header->FileName),
"!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
" for compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
Log().WarningFile(
GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
" instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
".\nRunning moc on the header\n ",
Quoted(header->FileName), "!\nBetter include ",
Quoted("moc_" + incKey.Base + ".cpp"),
" for compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
}
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
@ -780,20 +775,22 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (!ownMoc) {
// Don't allow <BASE>.moc include other than own in regular mode
std::string msg = cmStrCat(
"The file includes the moc file ", Quoted(incKey.Key),
",\nwhich seems to be the moc file from a different "
"source file.\nThis is not supported. Include ",
Quoted(sourceBase + ".moc"), " to run moc on this source file.");
LogFileError(GenT::MOC, sourceFile.FileName, msg);
LogFileError(
GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
",\nwhich seems to be the moc file from a different "
"source file.\nThis is not supported. Include ",
Quoted(sourceBase + ".moc"),
" to run moc on this source file."));
return false;
}
// Accept but issue a warning if moc isn't required
if (parseData.Macro.empty()) {
std::string msg = cmStrCat(
"The file includes the moc file ", Quoted(incKey.Key),
", but does not contain a ", MocConst().MacrosString(), " macro.");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
Log().WarningFile(GenT::MOC, sourceFile.FileName,
cmStrCat("The file includes the moc file ",
Quoted(incKey.Key),
", but does not contain a ",
MocConst().MacrosString(), " macro."));
}
// Create mapping
if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
@ -864,19 +861,16 @@ cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader(
}
std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders(
std::string const& fileBase) const
cm::string_view fileBase) const
{
std::ostringstream res;
{
std::string exts =
cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","),
'}'); // Compose result string
res << " " << fileBase << exts << '\n';
for (std::string const& path : MocConst().IncludePaths) {
res << " " << path << '/' << fileBase << exts << '\n';
}
std::string const exts =
cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}');
// Compose result string
std::string res = cmStrCat(" ", fileBase, exts, '\n');
for (std::string const& path : MocConst().IncludePaths) {
res += cmStrCat(" ", path, '/', fileBase, exts, '\n');
}
return res.str();
return res;
}
bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
@ -888,26 +882,24 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
if (handle) {
// Check if the output file would be generated from different source files
if (handle->SourceFile != sourceFileHandle) {
std::string msg = cmStrCat("The source files\n ",
Quoted(includerFileHandle->FileName), '\n');
std::string files =
cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
msg += '\n';
files += cmStrCat(" ", Quoted(item->FileName), '\n');
}
msg += "contain the same include string ";
msg += Quoted(includeString);
msg += ", but\nthe moc file would be generated from different "
"source files\n ";
msg += Quoted(sourceFileHandle->FileName);
msg += " and\n ";
msg += Quoted(handle->SourceFile->FileName);
msg += ".\nConsider to\n"
" - not include the \"moc_<NAME>.cpp\" file\n"
" - add a directory prefix to a \"<NAME>.moc\" include "
"(e.g \"sub/<NAME>.moc\")\n"
" - rename the source file(s)\n";
LogError(GenT::MOC, msg);
LogError(
GenT::MOC,
cmStrCat("The source files\n", files,
"contain the same include string ", Quoted(includeString),
", but\nthe moc file would be generated from different "
"source files\n ",
Quoted(sourceFileHandle->FileName), " and\n ",
Quoted(handle->SourceFile->FileName),
".\nConsider to\n"
" - not include the \"moc_<NAME>.cpp\" file\n"
" - add a directory prefix to a \"<NAME>.moc\" include "
"(e.g \"sub/<NAME>.moc\")\n"
" - rename the source file(s)\n"));
return false;
}
@ -921,7 +913,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(sourceFileHandle);
handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping in sources/headers map
MocRegisterMapping(handle, sourceIsHeader);
@ -993,26 +985,25 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
MappingHandleT const& handle = it->second;
if (handle->SourceFile != uiFileHandle) {
// The output file already gets generated - from a different .ui file!
std::string msg = cmStrCat("The source files\n ",
Quoted(includerFileHandle->FileName), '\n');
std::string files =
cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
msg += '\n';
files += cmStrCat(" ", Quoted(item->FileName), '\n');
}
msg += "contain the same include string ";
msg += Quoted(includeString);
msg += ", but\nthe uic file would be generated from different "
"user interface files\n ";
msg += Quoted(uiFileHandle->FileName);
msg += " and\n ";
msg += Quoted(handle->SourceFile->FileName);
msg += ".\nConsider to\n"
" - add a directory prefix to a \"ui_<NAME>.h\" include "
"(e.g \"sub/ui_<NAME>.h\")\n"
" - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
"include(s)\n";
LogError(GenT::UIC, msg);
LogError(
GenT::UIC,
cmStrCat(
"The source files\n", files, "contain the same include string ",
Quoted(includeString),
", but\nthe uic file would be generated from different "
"user interface files\n ",
Quoted(uiFileHandle->FileName), " and\n ",
Quoted(handle->SourceFile->FileName),
".\nConsider to\n"
" - add a directory prefix to a \"ui_<NAME>.h\" include "
"(e.g \"sub/ui_<NAME>.h\")\n"
" - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
"include(s)\n"));
return false;
}
// Add includer file to existing mapping
@ -1023,7 +1014,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(uiFileHandle);
handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping
Includes.emplace(includeString, std::move(handle));
}
@ -1080,16 +1071,15 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi(
// Log error
{
std::string msg =
std::string files;
for (std::string const& testFile : testFiles) {
files += cmStrCat(" ", Quoted(testFile), '\n');
}
LogFileError(
GenT::UIC, sourceFile,
cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
",\nbut the user interface file ", Quoted(searchFileName),
"\ncould not be found in the following locations\n");
for (std::string const& testFile : testFiles) {
msg += " ";
msg += Quoted(testFile);
msg += '\n';
}
LogFileError(GenT::UIC, sourceFile, msg);
"\ncould not be found in the following locations\n", files));
}
return SourceFileHandleT();
@ -1257,9 +1247,7 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency(
}
// Search in include directories
for (std::string const& includePath : MocConst().IncludePaths) {
ResPair res{ includePath, {} };
res.first += '/';
res.first += includeString;
ResPair res{ cmStrCat(includePath, '/', includeString), {} };
if (res.second.Load(res.first)) {
return res;
}
@ -1366,21 +1354,19 @@ void cmQtAutoMocUic::JobMocT::Process()
}
} else {
// Moc command failed
std::string msg =
cmStrCat("The moc process failed to compile\n ", Quoted(sourceFile),
"\ninto\n ", Quoted(outputFile));
if (Mapping->IncluderFiles.empty()) {
msg += ".\n";
} else {
msg += "\nincluded by\n";
std::string includers;
if (!Mapping->IncluderFiles.empty()) {
includers = "included by\n";
for (auto const& item : Mapping->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
msg += '\n';
includers += cmStrCat(" ", Quoted(item->FileName), '\n');
}
}
msg += result.ErrorMessage;
LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
LogCommandError(GenT::MOC,
cmStrCat("The moc process failed to compile\n ",
Quoted(sourceFile), "\ninto\n ",
Quoted(outputFile), '\n', includers,
result.ErrorMessage),
cmd, result.StdOut);
}
}
@ -1414,16 +1400,16 @@ void cmQtAutoMocUic::JobUicT::Process()
}
} else {
// Uic command failed
std::string msg =
cmStrCat("The uic process failed to compile\n ", Quoted(sourceFile),
"\ninto\n ", Quoted(outputFile), "\nincluded by\n");
std::string includers;
for (auto const& item : Mapping->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
msg += '\n';
includers += cmStrCat(" ", Quoted(item->FileName), '\n');
}
msg += result.ErrorMessage;
LogCommandError(GenT::UIC, msg, cmd, result.StdOut);
LogCommandError(GenT::UIC,
cmStrCat("The uic process failed to compile\n ",
Quoted(sourceFile), "\ninto\n ",
Quoted(outputFile), "\nincluded by\n", includers,
result.ErrorMessage),
cmd, result.StdOut);
}
}
@ -1436,19 +1422,14 @@ void cmQtAutoMocUic::JobMocsCompilationT::Process()
if (MocEval().CompFiles.empty()) {
// Placeholder content
content += "// No files found that require moc or the moc files are "
"included\n";
content += "enum some_compilers { need_more_than_nothing };\n";
"included\n"
"enum some_compilers { need_more_than_nothing };\n";
} else {
// Valid content
char const clampB = BaseConst().MultiConfig ? '<' : '"';
char const clampE = BaseConst().MultiConfig ? '>' : '"';
for (std::string const& mocfile : MocEval().CompFiles) {
content += "#include ";
content += clampB;
content += mocfile;
content += clampE;
content += '\n';
}
const bool mc = BaseConst().MultiConfig;
cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
}
std::string const& compAbs = MocConst().CompFileAbs;
@ -1484,22 +1465,21 @@ cmQtAutoMocUic::~cmQtAutoMocUic() = default;
bool cmQtAutoMocUic::Init(cmMakefile* makefile)
{
// Utility lambdas
auto InfoGet = [makefile](const char* key) {
return makefile->GetSafeDefinition(key);
auto InfoGet = [makefile](cm::string_view key) {
return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetBool = [makefile](const char* key) {
return makefile->IsOn(key);
auto InfoGetBool = [makefile](cm::string_view key) {
return makefile->IsOn(std::string(key));
};
auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> {
std::vector<std::string> list =
cmExpandedList(makefile->GetSafeDefinition(key));
return list;
auto InfoGetList =
[makefile](cm::string_view key) -> std::vector<std::string> {
return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
};
auto InfoGetLists =
[makefile](const char* key) -> std::vector<std::vector<std::string>> {
[makefile](cm::string_view key) -> std::vector<std::vector<std::string>> {
std::vector<std::vector<std::string>> lists;
{
std::string const value = makefile->GetSafeDefinition(key);
std::string const value = makefile->GetSafeDefinition(std::string(key));
std::string::size_type pos = 0;
while (pos < value.size()) {
std::string::size_type next = value.find(ListSep, pos);
@ -1517,38 +1497,30 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
}
return lists;
};
auto InfoGetConfig = [makefile, this](const char* key) -> std::string {
const char* valueConf = nullptr;
{
std::string keyConf = cmStrCat(key, '_', InfoConfig());
valueConf = makefile->GetDefinition(keyConf);
auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
if (const char* valueConf =
makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
return std::string(valueConf);
}
if (valueConf == nullptr) {
return makefile->GetSafeDefinition(key);
}
return std::string(valueConf);
return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetConfigList =
[&InfoGetConfig](const char* key) -> std::vector<std::string> {
std::vector<std::string> list = cmExpandedList(InfoGetConfig(key));
return list;
[&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
return cmExpandedList(InfoGetConfig(key));
};
auto LogInfoError = [this](std::string const& msg) -> bool {
std::ostringstream err;
err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
this->Log().Error(GenT::GEN, err.str());
auto LogInfoError = [this](cm::string_view msg) -> bool {
this->Log().Error(GenT::GEN,
cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
return false;
};
auto MatchSizes = [&LogInfoError](const char* keyA, const char* keyB,
auto MatchSizes = [&LogInfoError](cm::string_view keyA, cm::string_view keyB,
std::size_t sizeA,
std::size_t sizeB) -> bool {
if (sizeA == sizeB) {
return true;
}
std::ostringstream err;
err << "Lists sizes mismatch " << keyA << '(' << sizeA << ") " << keyB
<< '(' << sizeB << ')';
return LogInfoError(err.str());
return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA,
") ", keyB, '(', sizeB, ')'));
};
// -- Read info file
@ -1590,10 +1562,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
return LogInfoError("CMake executable file name missing.");
}
if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
std::string error =
cmStrCat("The CMake executable ", Quoted(BaseConst_.CMakeExecutable),
" does not exist.");
return LogInfoError(error);
return LogInfoError(cmStrCat("The CMake executable ",
Quoted(BaseConst_.CMakeExecutable),
" does not exist."));
}
BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
if (BaseConst_.ParseCacheFile.empty()) {
@ -1620,10 +1591,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
MocConst_.Enabled = true;
// Load the executable file time
if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
std::string error =
cmStrCat("The moc executable ", Quoted(MocConst_.Executable),
" does not exist.");
return LogInfoError(error);
return LogInfoError(cmStrCat("The moc executable ",
Quoted(MocConst_.Executable),
" does not exist."));
}
for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
MocConst_.SkipList.insert(std::move(sfl));
@ -1639,12 +1609,11 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
{
auto addFilter = [this, &LogInfoError](std::string const& key,
std::string const& exp) -> bool {
auto filterErr = [&LogInfoError, &key, &exp](const char* err) -> bool {
std::ostringstream ferr;
ferr << "AUTOMOC_DEPEND_FILTERS: " << err << '\n';
ferr << " Key: " << Quoted(key) << '\n';
ferr << " Exp: " << Quoted(exp) << '\n';
return LogInfoError(ferr.str());
auto filterErr = [&LogInfoError, &key,
&exp](cm::string_view err) -> bool {
return LogInfoError(cmStrCat("AUTOMOC_DEPEND_FILTERS: ", err, '\n',
" Key: ", Quoted(key), '\n',
" Exp: ", Quoted(exp), '\n'));
};
if (key.empty()) {
return filterErr("Key is empty");
@ -1688,10 +1657,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
UicConst_.Enabled = true;
// Load the executable file time
if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
std::string error =
cmStrCat("The uic executable ", Quoted(UicConst_.Executable),
" does not exist.");
return LogInfoError(error);
return LogInfoError(cmStrCat("The uic executable ",
Quoted(UicConst_.Executable),
" does not exist."));
}
for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
UicConst_.SkipList.insert(std::move(sfl));
@ -1699,8 +1667,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
{
const char* keyFiles = "AM_UIC_OPTIONS_FILES";
const char* keyOpts = "AM_UIC_OPTIONS_OPTIONS";
cm::string_view const keyFiles = "AM_UIC_OPTIONS_FILES";
cm::string_view const keyOpts = "AM_UIC_OPTIONS_OPTIONS";
auto sources = InfoGetList(keyFiles);
auto options = InfoGetLists(keyOpts);
if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) {
@ -1742,8 +1710,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Headers
{
// Get file lists
const char* keyFiles = "AM_HEADERS";
const char* keyFlags = "AM_HEADERS_FLAGS";
cm::string_view const keyFiles = "AM_HEADERS";
cm::string_view const keyFlags = "AM_HEADERS_FLAGS";
std::vector<std::string> files = InfoGetList(keyFiles);
std::vector<std::string> flags = InfoGetList(keyFlags);
std::vector<std::string> builds;
@ -1751,7 +1719,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
return false;
}
if (MocConst().Enabled) {
const char* keyPaths = "AM_HEADERS_BUILD_PATHS";
cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS";
builds = InfoGetList(keyPaths);
if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
return false;
@ -1778,8 +1746,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Sources
{
const char* keyFiles = "AM_SOURCES";
const char* keyFlags = "AM_SOURCES_FLAGS";
cm::string_view const keyFiles = "AM_SOURCES";
cm::string_view const keyFlags = "AM_SOURCES_FLAGS";
std::vector<std::string> files = InfoGetList(keyFiles);
std::vector<std::string> flags = InfoGetList(keyFlags);
if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
@ -1807,12 +1775,12 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Moc predefs file
if (!MocConst_.PredefsCmd.empty()) {
MocConst_.PredefsFileRel = "moc_predefs";
if (BaseConst_.MultiConfig) {
MocConst_.PredefsFileRel += '_';
MocConst_.PredefsFileRel += InfoConfig();
MocConst_.PredefsFileRel =
cmStrCat("moc_predefs_", InfoConfig(), ".h");
} else {
MocConst_.PredefsFileRel = "moc_predefs.h";
}
MocConst_.PredefsFileRel += ".h";
MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel);
}
@ -1825,14 +1793,14 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
MocConst_.IncludePaths.reserve(includes.size());
// Append project directories only
{
std::array<std::string const*, 2> const movePaths = {
{ &BaseConst().ProjectBinaryDir, &BaseConst().ProjectSourceDir }
std::initializer_list<cm::string_view> const movePaths = {
BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir
};
for (std::string const* ppath : movePaths) {
for (cm::string_view const& ppath : movePaths) {
std::list<std::string>::iterator it = includes.begin();
while (it != includes.end()) {
std::string const& path = *it;
if (cmHasPrefix(path, *ppath)) {
if (cmHasPrefix(path, ppath)) {
MocConst_.IncludePaths.push_back(path);
it = includes.erase(it);
} else {
@ -1944,22 +1912,19 @@ void cmQtAutoMocUic::SettingsFileRead()
// Compose current settings strings
{
cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
std::string const sep(";");
auto cha = [&cryptoHash, &sep](std::string const& value) {
auto cha = [&cryptoHash](cm::string_view value) {
cryptoHash.Append(value);
cryptoHash.Append(sep);
cryptoHash.Append(";");
};
if (MocConst_.Enabled) {
cryptoHash.Initialize();
cha(MocConst().Executable);
for (auto const& value : MocConst().AllOptions) {
cha(value);
}
std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(),
cha);
cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE");
for (auto const& value : MocConst().PredefsCmd) {
cha(value);
}
std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(),
cha);
for (auto const& filter : MocConst().DependFilters) {
cha(filter.Key);
}
@ -1972,14 +1937,11 @@ void cmQtAutoMocUic::SettingsFileRead()
if (UicConst().Enabled) {
cryptoHash.Initialize();
cha(UicConst().Executable);
for (auto const& value : UicConst().TargetOptions) {
cha(value);
}
std::for_each(UicConst().TargetOptions.begin(),
UicConst().TargetOptions.end(), cha);
for (const auto& item : UicConst().Options) {
cha(item.first);
for (auto const& svalue : item.second) {
cha(svalue);
}
std::for_each(item.second.begin(), item.second.end(), cha);
}
SettingsStringUic_ = cryptoHash.FinalizeHex();
}
@ -2027,13 +1989,10 @@ bool cmQtAutoMocUic::SettingsFileWrite()
// Compose settings file content
std::string content;
{
auto SettingAppend = [&content](const char* key,
std::string const& value) {
auto SettingAppend = [&content](cm::string_view key,
cm::string_view value) {
if (!value.empty()) {
content += key;
content += ':';
content += value;
content += '\n';
content += cmStrCat(key, ':', value, '\n');
}
};
SettingAppend("moc", SettingsStringMoc_);
@ -2054,7 +2013,7 @@ bool cmQtAutoMocUic::SettingsFileWrite()
void cmQtAutoMocUic::ParseCacheRead()
{
const char* reason = nullptr;
cm::string_view reason;
// Don't read the cache if it is invalid
if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
reason = "Refreshing parse cache because it doesn't exist.";
@ -2066,7 +2025,7 @@ void cmQtAutoMocUic::ParseCacheRead()
"Refreshing parse cache because it is older than the CMake executable.";
}
if (reason != nullptr) {
if (!reason.empty()) {
// Don't read but refresh the complete parse cache
if (Log().Verbose()) {
Log().Info(GenT::GEN, reason);
@ -2115,19 +2074,13 @@ void cmQtAutoMocUic::Abort(bool error)
}
std::string cmQtAutoMocUic::AbsoluteBuildPath(
std::string const& relativePath) const
cm::string_view relativePath) const
{
std::string res(BaseConst().AutogenBuildDir);
res += '/';
res += relativePath;
return res;
return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
}
std::string cmQtAutoMocUic::AbsoluteIncludePath(
std::string const& relativePath) const
cm::string_view relativePath) const
{
std::string res(BaseConst().AutogenIncludeDir);
res += '/';
res += relativePath;
return res;
return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
}

View File

@ -9,6 +9,7 @@
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmWorkerPool.h"
#include "cm_string_view.hxx"
#include "cmsys/RegularExpression.hxx"
#include <atomic>
@ -333,10 +334,10 @@ public:
UicEvalT& UicEval() const { return Gen()->UicEval(); }
// -- Error logging with automatic abort
void LogError(GenT genType, std::string const& message) const;
void LogFileError(GenT genType, std::string const& filename,
std::string const& message) const;
void LogCommandError(GenT genType, std::string const& message,
void LogError(GenT genType, cm::string_view message) const;
void LogFileError(GenT genType, cm::string_view filename,
cm::string_view message) const;
void LogCommandError(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
@ -429,7 +430,7 @@ public:
SourceFileHandleT MocFindIncludedHeader(
std::string const& includerDir, std::string const& includeBase) const;
SourceFileHandleT MocFindHeader(std::string const& basePath) const;
std::string MocMessageTestHeaders(std::string const& fileBase) const;
std::string MocMessageTestHeaders(cm::string_view fileBase) const;
bool MocRegisterIncluded(std::string const& includeString,
SourceFileHandleT includerFileHandle,
SourceFileHandleT sourceFileHandle,
@ -531,8 +532,8 @@ public:
void AbortSuccess() { Abort(false); }
// -- Utility
std::string AbsoluteBuildPath(std::string const& relativePath) const;
std::string AbsoluteIncludePath(std::string const& relativePath) const;
std::string AbsoluteBuildPath(cm::string_view relativePath) const;
std::string AbsoluteIncludePath(cm::string_view relativePath) const;
template <class JOBTYPE>
void CreateParseJobs(SourceFileMapT const& sourceMap);

View File

@ -1,9 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoRcc.h"
#include "cmQtAutoGen.h"
#include <sstream>
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
@ -11,10 +8,12 @@
#include "cmFileLockResult.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmQtAutoGen.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cm_string_view.hxx"
// -- Class methods
#include <algorithm>
cmQtAutoRcc::cmQtAutoRcc() = default;
@ -23,36 +22,27 @@ cmQtAutoRcc::~cmQtAutoRcc() = default;
bool cmQtAutoRcc::Init(cmMakefile* makefile)
{
// -- Utility lambdas
auto InfoGet = [makefile](std::string const& key) {
return makefile->GetSafeDefinition(key);
auto InfoGet = [makefile](cm::string_view key) {
return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetList =
[makefile](std::string const& key) -> std::vector<std::string> {
std::vector<std::string> list =
cmExpandedList(makefile->GetSafeDefinition(key));
return list;
[makefile](cm::string_view key) -> std::vector<std::string> {
return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
};
auto InfoGetConfig = [makefile,
this](std::string const& key) -> std::string {
const char* valueConf = nullptr;
{
std::string keyConf = cmStrCat(key, '_', InfoConfig());
valueConf = makefile->GetDefinition(keyConf);
auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
if (const char* valueConf =
makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
return std::string(valueConf);
}
if (valueConf == nullptr) {
return makefile->GetSafeDefinition(key);
}
return std::string(valueConf);
return makefile->GetSafeDefinition(std::string(key));
};
auto InfoGetConfigList =
[&InfoGetConfig](std::string const& key) -> std::vector<std::string> {
std::vector<std::string> list = cmExpandedList(InfoGetConfig(key));
return list;
[&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
return cmExpandedList(InfoGetConfig(key));
};
auto LogInfoError = [this](std::string const& msg) -> bool {
std::ostringstream err;
err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
this->Log().Error(GenT::RCC, err.str());
auto LogInfoError = [this](cm::string_view msg) -> bool {
this->Log().Error(GenT::RCC,
cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
return false;
};
@ -79,9 +69,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
// - Rcc executable
RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
if (!RccExecutableTime_.Load(RccExecutable_)) {
std::string error = cmStrCat("The rcc executable ", Quoted(RccExecutable_),
" does not exist.");
return LogInfoError(error);
return LogInfoError(cmStrCat("The rcc executable ", Quoted(RccExecutable_),
" does not exist."));
}
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
@ -169,25 +158,27 @@ bool cmQtAutoRcc::Process()
std::string cmQtAutoRcc::MultiConfigOutput() const
{
static std::string const suffix = "_CMAKE_";
std::string res = cmStrCat(RccPathChecksum_, '/',
AppendFilenameSuffix(RccFileName_, suffix));
return res;
return cmStrCat(RccPathChecksum_, '/',
AppendFilenameSuffix(RccFileName_, "_CMAKE_"));
}
bool cmQtAutoRcc::SettingsFileRead()
{
// Compose current settings strings
{
cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
std::string const sep(" ~~~ ");
{
std::string str =
cmStrCat(RccExecutable_, sep, cmJoin(RccListOptions_, ";"), sep,
QrcFile_, sep, RccPathChecksum_, sep, RccFileName_, sep,
cmJoin(Options_, ";"), sep, cmJoin(Inputs_, ";"), sep);
SettingsString_ = crypt.HashString(str);
}
cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
auto cha = [&cryptoHash](cm::string_view value) {
cryptoHash.Append(value);
cryptoHash.Append(";");
};
cha(RccExecutable_);
std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha);
cha(QrcFile_);
cha(RccPathChecksum_);
cha(RccFileName_);
std::for_each(Options_.begin(), Options_.end(), cha);
std::for_each(Inputs_.begin(), Inputs_.end(), cha);
SettingsString_ = cryptoHash.FinalizeHex();
}
// Make sure the settings file exists
@ -272,10 +263,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
{
// Test if the rcc input file exists
if (!QrcFileTime_.Load(QrcFile_)) {
std::string error;
error =
cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist");
Log().ErrorFile(GenT::RCC, QrcFile_, error);
Log().ErrorFile(
GenT::RCC, QrcFile_,
cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist"));
return false;
}
@ -342,10 +332,9 @@ bool cmQtAutoRcc::TestResources(bool& generate)
// Check if the resource file exists
cmFileTime fileTime;
if (!fileTime.Load(resFile)) {
std::string error;
error = cmStrCat("Could not find the resource file\n ", Quoted(resFile),
'\n');
Log().ErrorFile(GenT::RCC, QrcFile_, error);
Log().ErrorFile(GenT::RCC, QrcFile_,
cmStrCat("Could not find the resource file\n ",
Quoted(resFile), '\n'));
return false;
}
// Check if the resource file is newer than the rcc output file
@ -367,10 +356,9 @@ bool cmQtAutoRcc::TestInfoFile()
// Test if the rcc output file is older than the info file
if (RccFileTime_.Older(InfoFileTime())) {
if (Log().Verbose()) {
std::string reason =
cmStrCat("Touching ", Quoted(RccFileOutput_),
" because it is older than ", Quoted(InfoFile()));
Log().Info(GenT::RCC, reason);
Log().Info(GenT::RCC,
cmStrCat("Touching ", Quoted(RccFileOutput_),
" because it is older than ", Quoted(InfoFile())));
}
// Touch build file
if (!cmSystemTools::Touch(RccFileOutput_, false)) {
@ -402,13 +390,9 @@ bool cmQtAutoRcc::GenerateRcc()
// Log reason and command
if (Log().Verbose()) {
std::string msg = Reason;
if (!msg.empty() && (msg.back() != '\n')) {
msg += '\n';
}
msg += QuotedCommand(cmd);
msg += '\n';
Log().Info(GenT::RCC, msg);
Log().Info(GenT::RCC,
cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n",
QuotedCommand(cmd), '\n'));
}
std::string rccStdOut;
@ -419,12 +403,11 @@ bool cmQtAutoRcc::GenerateRcc()
cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
if (!result || (retVal != 0)) {
// rcc process failed
{
std::string err =
cmStrCat("The rcc process failed to compile\n ", Quoted(QrcFile_),
"\ninto\n ", Quoted(RccFileOutput_));
Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr);
}
Log().ErrorCommand(GenT::RCC,
cmStrCat("The rcc process failed to compile\n ",
Quoted(QrcFile_), "\ninto\n ",
Quoted(RccFileOutput_)),
cmd, rccStdOut + rccStdErr);
cmSystemTools::RemoveFile(RccFileOutput_);
return false;
}