Autogen: Add and use cmQtAutoGenerator base class

Adds the new base class `cmQtAutoGenerator` which contains common
variables and methods used by `cmQtAutoGeneratorMocUic` and
`cmQtAutoGeneratorRcc`.
This commit is contained in:
Sebastian Holtermann 2017-11-18 11:29:26 +01:00
parent 27ed3b3537
commit 75819b8626
9 changed files with 488 additions and 759 deletions

View File

@ -9,6 +9,7 @@ set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJ
set(AM_BUILD_DIR @_build_dir@)
set(AM_SOURCES @_sources@)
set(AM_HEADERS @_headers@)
set(AM_SETTINGS_FILE @_settings_file@)
# Qt environment
set(AM_QT_VERSION_MAJOR @_qt_version_major@)
set(AM_QT_VERSION_MINOR @_qt_version_minor@)

View File

@ -312,6 +312,8 @@ set(SRCS
cmQtAutoGen.cxx
cmQtAutoGen.h
cmQtAutoGenDigest.h
cmQtAutoGenerator.cxx
cmQtAutoGenerator.h
cmQtAutoGeneratorInitializer.cxx
cmQtAutoGeneratorInitializer.h
cmQtAutoGeneratorMocUic.cxx

View File

@ -0,0 +1,320 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
#include "cmAlgorithms.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"
// -- Static functions
static std::string HeadLine(std::string const& title)
{
std::string head = title;
head += '\n';
head.append(head.size() - 1, '-');
head += '\n';
return head;
}
static std::string QuotedCommand(std::vector<std::string> const& command)
{
std::string res;
for (std::string const& item : command) {
if (!res.empty()) {
res.push_back(' ');
}
std::string const cesc = cmQtAutoGen::Quoted(item);
if (item.empty() || (cesc.size() > (item.size() + 2)) ||
(cesc.find(' ') != std::string::npos)) {
res += cesc;
} else {
res += item;
}
}
return res;
}
// -- Class methods
cmQtAutoGenerator::cmQtAutoGenerator()
: Verbose(cmSystemTools::HasEnv("VERBOSE"))
, ColorOutput(true)
{
{
std::string colorEnv;
cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
this->ColorOutput = cmSystemTools::IsOn(colorEnv.c_str());
}
}
}
bool cmQtAutoGenerator::Run(std::string const& infoFile,
std::string const& config)
{
// Info settings
this->InfoFile = infoFile;
cmSystemTools::ConvertToUnixSlashes(this->InfoFile);
this->InfoDir = cmSystemTools::GetFilenamePath(infoFile);
this->InfoConfig = config;
cmake cm(cmake::RoleScript);
cm.SetHomeOutputDirectory(this->InfoDir);
cm.SetHomeDirectory(this->InfoDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(this->InfoDir);
snapshot.GetDirectory().SetCurrentSource(this->InfoDir);
auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
gg.SetCurrentMakefile(makefile.get());
return this->Process(makefile.get());
}
void cmQtAutoGenerator::LogBold(std::string const& message) const
{
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, this->ColorOutput);
}
void cmQtAutoGenerator::LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += ": ";
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGenerator::LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += " warning:";
if (message.find('\n') == std::string::npos) {
// Single line message
msg.push_back(' ');
} else {
// Multi line message
msg.push_back('\n');
}
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGenerator::LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string msg = " ";
msg += cmQtAutoGen::Quoted(filename);
msg.push_back('\n');
// Message
msg += message;
this->LogWarning(genType, msg);
}
void cmQtAutoGenerator::LogError(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " error");
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
void cmQtAutoGenerator::LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string emsg = " ";
emsg += cmQtAutoGen::Quoted(filename);
emsg += '\n';
// Message
emsg += message;
this->LogError(genType, emsg);
}
void cmQtAutoGenerator::LogCommandError(
cmQtAutoGen::Generator genType, std::string const& message,
std::vector<std::string> const& command, std::string const& output) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::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');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
/**
* @brief Generates the parent directory of the given file on demand
* @return True on success
*/
bool cmQtAutoGenerator::MakeParentDirectory(cmQtAutoGen::Generator genType,
std::string const& filename) const
{
bool success = true;
std::string const dirName = cmSystemTools::GetFilenamePath(filename);
if (!dirName.empty()) {
if (!cmSystemTools::MakeDirectory(dirName)) {
this->LogFileError(genType, filename,
"Could not create parent directory");
success = false;
}
}
return success;
}
/**
* @brief Tests if buildFile is older than sourceFile
* @return True if buildFile is older than sourceFile.
* False may indicate an error.
*/
bool cmQtAutoGenerator::FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile,
std::string* error)
{
int result = 0;
if (cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result)) {
return (result < 0);
}
if (error != nullptr) {
error->append(
"File modification time comparison failed for the files\n ");
error->append(cmQtAutoGen::Quoted(buildFile));
error->append("\nand\n ");
error->append(cmQtAutoGen::Quoted(sourceFile));
}
return false;
}
bool cmQtAutoGenerator::FileRead(std::string& content,
std::string const& filename,
std::string* error)
{
bool success = false;
if (cmSystemTools::FileExists(filename)) {
std::size_t const length = cmSystemTools::FileLength(filename);
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
if (ifs) {
content.resize(length);
ifs.read(&content.front(), content.size());
if (ifs) {
success = true;
} else {
content.clear();
if (error != nullptr) {
error->append("Reading from the file failed.");
}
}
} else if (error != nullptr) {
error->append("Opening the file for reading failed.");
}
} else if (error != nullptr) {
error->append("The file does not exist.");
}
return success;
}
bool cmQtAutoGenerator::FileWrite(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& content)
{
std::string error;
// Make sure the parent directory exists
if (this->MakeParentDirectory(genType, filename)) {
cmsys::ofstream outfile;
outfile.open(filename.c_str(),
(std::ios::out | std::ios::binary | std::ios::trunc));
if (outfile) {
outfile << content;
// Check for write errors
if (!outfile.good()) {
error = "File writing failed";
}
} else {
error = "Opening file for writing failed";
}
}
if (!error.empty()) {
this->LogFileError(genType, filename, error);
return false;
}
return true;
}
bool cmQtAutoGenerator::FileDiffers(std::string const& filename,
std::string const& content)
{
bool differs = true;
{
std::string oldContents;
if (this->FileRead(oldContents, filename)) {
differs = (oldContents != content);
}
}
return differs;
}
/**
* @brief Runs a command and returns true on success
* @return True on success
*/
bool cmQtAutoGenerator::RunCommand(std::vector<std::string> const& command,
std::string& output) const
{
// Log command
if (this->Verbose) {
std::string qcmd = QuotedCommand(command);
qcmd.push_back('\n');
cmSystemTools::Stdout(qcmd.c_str(), qcmd.size());
}
// Execute command
int retVal = 0;
bool res = cmSystemTools::RunSingleCommand(
command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE);
return (res && (retVal == 0));
}

View File

@ -0,0 +1,76 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmQtAutoGenerator_h
#define cmQtAutoGenerator_h
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmQtAutoGen.h"
#include <string>
#include <vector>
class cmMakefile;
class cmQtAutoGenerator
{
CM_DISABLE_COPY(cmQtAutoGenerator)
public:
cmQtAutoGenerator();
virtual ~cmQtAutoGenerator() = default;
bool Run(std::string const& infoFile, std::string const& config);
std::string const& GetInfoFile() const { return InfoFile; }
std::string const& GetInfoDir() const { return InfoDir; }
std::string const& GetInfoConfig() const { return InfoConfig; }
bool GetVerbose() const { return Verbose; }
protected:
// -- Central processing
virtual bool Process(cmMakefile* makefile) = 0;
// -- Log info
void LogBold(std::string const& message) const;
void LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const;
// -- Log warning
void LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
// -- Log error
void LogError(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
void LogCommandError(cmQtAutoGen::Generator genType,
std::string const& message,
std::vector<std::string> const& command,
std::string const& output) const;
// -- Utility
bool MakeParentDirectory(cmQtAutoGen::Generator genType,
std::string const& filename) const;
bool FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile,
std::string* error = nullptr);
bool FileRead(std::string& content, std::string const& filename,
std::string* error = nullptr);
bool FileWrite(cmQtAutoGen::Generator genType, std::string const& filename,
std::string const& content);
bool FileDiffers(std::string const& filename, std::string const& content);
bool RunCommand(std::vector<std::string> const& command,
std::string& output) const;
private:
// -- Info settings
std::string InfoFile;
std::string InfoDir;
std::string InfoConfig;
// -- Settings
bool Verbose;
bool ColorOutput;
};
#endif

View File

@ -1061,7 +1061,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
currentLine.push_back(cmSystemTools::GetCMakeCommand());
currentLine.push_back("-E");
currentLine.push_back("cmake_autogen");
currentLine.push_back(autogenInfoDir);
currentLine.push_back(autogenInfoDir + "/AutogenInfo.cmake");
currentLine.push_back("$<CONFIGURATION>");
commandLines.push_back(std::move(currentLine));
}
@ -1197,12 +1197,19 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
cmQtAutoGen::MultiConfigName(multiConfig));
AddDefinitionEscaped(makefile, "_build_dir",
GetAutogenTargetBuildDir(target));
AddDefinitionEscaped(makefile, "_sources", digest.Sources);
AddDefinitionEscaped(makefile, "_headers", digest.Headers);
AddDefinitionEscaped(makefile, "_qt_version_major", digest.QtVersionMajor);
AddDefinitionEscaped(makefile, "_qt_version_minor", digest.QtVersionMinor);
{
if (digest.MocEnabled || digest.UicEnabled) {
{
std::string settingsFile = GetAutogenTargetFilesDir(target);
cmSystemTools::ConvertToUnixSlashes(settingsFile);
settingsFile += "/AutogenOldSettings.cmake";
AddDefinitionEscaped(makefile, "_settings_file", settingsFile);
}
AddDefinitionEscaped(makefile, "_sources", digest.Sources);
AddDefinitionEscaped(makefile, "_headers", digest.Headers);
SetupAcquireSkipFiles(digest, setup);
if (digest.MocEnabled) {
SetupAutoTargetMoc(digest, configDefault, configsList, setup);

View File

@ -3,8 +3,6 @@
#include "cmQtAutoGen.h"
#include "cmQtAutoGeneratorMocUic.h"
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
#include <algorithm>
#include <array>
#include <list>
@ -15,12 +13,8 @@
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFilePathChecksum.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"
@ -35,33 +29,6 @@ static const char* SettingsKeyUic = "AM_UIC_SETTINGS_HASH";
// -- Static functions
static std::string HeadLine(std::string const& title)
{
std::string head = title;
head += '\n';
head.append(head.size() - 1, '-');
head += '\n';
return head;
}
static std::string QuotedCommand(std::vector<std::string> const& command)
{
std::string res;
for (std::string const& item : command) {
if (!res.empty()) {
res.push_back(' ');
}
std::string const cesc = cmQtAutoGen::Quoted(item);
if (item.empty() || (cesc.size() > (item.size() + 2)) ||
(cesc.find(' ') != std::string::npos)) {
res += cesc;
} else {
res += item;
}
}
return res;
}
static std::string SubDirPrefix(std::string const& fileName)
{
std::string res(cmSystemTools::GetFilenamePath(fileName));
@ -71,56 +38,6 @@ static std::string SubDirPrefix(std::string const& fileName)
return res;
}
static bool ReadFile(std::string& content, std::string const& filename,
std::string* error = nullptr)
{
bool success = false;
if (cmSystemTools::FileExists(filename)) {
std::size_t const length = cmSystemTools::FileLength(filename);
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
if (ifs) {
content.resize(length);
ifs.read(&content.front(), content.size());
if (ifs) {
success = true;
} else {
content.clear();
if (error != nullptr) {
error->append("Reading from the file failed.");
}
}
} else if (error != nullptr) {
error->append("Opening the file for reading failed.");
}
} else if (error != nullptr) {
error->append("The file does not exist.");
}
return success;
}
/**
* @brief Tests if buildFile is older than sourceFile
* @return True if buildFile is older than sourceFile.
* False may indicate an error.
*/
static bool FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile,
std::string* error = nullptr)
{
int result = 0;
if (cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result)) {
return (result < 0);
}
if (error != nullptr) {
error->append(
"File modification time comparison failed for the files\n ");
error->append(cmQtAutoGen::Quoted(buildFile));
error->append("\nand\n ");
error->append(cmQtAutoGen::Quoted(sourceFile));
}
return false;
}
static bool ListContains(std::vector<std::string> const& list,
std::string const& entry)
{
@ -132,21 +49,11 @@ static bool ListContains(std::vector<std::string> const& list,
cmQtAutoGeneratorMocUic::cmQtAutoGeneratorMocUic()
: MultiConfig(cmQtAutoGen::WRAP)
, IncludeProjectDirsBefore(false)
, Verbose(cmSystemTools::HasEnv("VERBOSE"))
, ColorOutput(true)
, MocSettingsChanged(false)
, MocPredefsChanged(false)
, MocRelaxedMode(false)
, UicSettingsChanged(false)
{
{
std::string colorEnv;
cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
this->ColorOutput = cmSystemTools::IsOn(colorEnv.c_str());
}
}
// Precompile regular expressions
this->MocRegExpInclude.compile(
"[\n][ \t]*#[ \t]*include[ \t]+"
@ -155,39 +62,7 @@ cmQtAutoGeneratorMocUic::cmQtAutoGeneratorMocUic()
"[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
}
bool cmQtAutoGeneratorMocUic::Run(std::string const& targetDirectory,
std::string const& config)
{
cmake cm(cmake::RoleScript);
cm.SetHomeOutputDirectory(targetDirectory);
cm.SetHomeDirectory(targetDirectory);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(targetDirectory);
snapshot.GetDirectory().SetCurrentSource(targetDirectory);
auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
gg.SetCurrentMakefile(makefile.get());
bool success = false;
if (this->InitInfoFile(makefile.get(), targetDirectory, config)) {
// Read latest settings
this->SettingsFileRead(makefile.get());
if (this->Process()) {
// Write current settings
if (this->SettingsFileWrite()) {
success = true;
}
}
}
return success;
}
bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
std::string const& targetDirectory,
std::string const& config)
bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile)
{
// -- Meta
this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions();
@ -231,12 +106,12 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
}
return lists;
};
auto InfoGetConfig = [makefile, &config](const char* key) -> std::string {
auto InfoGetConfig = [makefile, this](const char* key) -> std::string {
const char* valueConf = nullptr;
{
std::string keyConf = key;
keyConf += '_';
keyConf += config;
keyConf += this->GetInfoConfig();
valueConf = makefile->GetDefinition(keyConf);
}
if (valueConf == nullptr) {
@ -252,11 +127,8 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
};
// -- Read info file
this->InfoFile = cmSystemTools::CollapseFullPath(targetDirectory);
cmSystemTools::ConvertToUnixSlashes(this->InfoFile);
this->InfoFile += "/AutogenInfo.cmake";
if (!makefile->ReadListFile(this->InfoFile.c_str())) {
this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
if (!makefile->ReadListFile(this->GetInfoFile().c_str())) {
this->LogFileError(cmQtAutoGen::GEN, this->GetInfoFile(),
"File processing failed");
return false;
}
@ -266,7 +138,19 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
this->ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX");
if (this->ConfigSuffix.empty()) {
this->ConfigSuffix = "_";
this->ConfigSuffix += config;
this->ConfigSuffix += this->GetInfoConfig();
}
this->SettingsFile = InfoGetConfig("AM_SETTINGS_FILE");
if (!this->SettingsFile.empty()) {
if (this->MultiConfig != cmQtAutoGen::SINGLE) {
this->SettingsFile = cmQtAutoGen::AppendFilenameSuffix(
this->SettingsFile, this->ConfigSuffix);
}
} else {
this->LogFileError(cmQtAutoGen::GEN, this->GetInfoFile(),
"Settings file is missing");
return false;
}
// - Files and directories
@ -278,7 +162,7 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
this->AutogenBuildDir = InfoGet("AM_BUILD_DIR");
if (this->AutogenBuildDir.empty()) {
this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
this->LogFileError(cmQtAutoGen::GEN, this->GetInfoFile(),
"Autogen build directory missing");
return false;
}
@ -291,7 +175,7 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
// Check Qt version
if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
this->LogFileError(cmQtAutoGen::GEN, this->GetInfoFile(),
"Unsupported Qt version: " +
cmQtAutoGen::Quoted(this->QtMajorVersion));
return false;
@ -341,7 +225,7 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
}
} else {
this->LogFileError(
cmQtAutoGen::MOC, this->InfoFile,
cmQtAutoGen::MOC, this->GetInfoFile(),
"AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
return false;
}
@ -362,7 +246,7 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
std::ostringstream ost;
ost << "files/options lists sizes missmatch (" << sources.size() << "/"
<< options.size() << ")";
this->LogFileError(cmQtAutoGen::UIC, this->InfoFile, ost.str());
this->LogFileError(cmQtAutoGen::UIC, this->GetInfoFile(), ost.str());
return false;
}
auto fitEnd = sources.cend();
@ -535,17 +419,6 @@ bool cmQtAutoGeneratorMocUic::InitInfoFile(cmMakefile* makefile,
}
}
// - Old settings file
{
this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory);
cmSystemTools::ConvertToUnixSlashes(this->SettingsFile);
this->SettingsFile += "/AutogenOldSettings";
if (this->MultiConfig != cmQtAutoGen::SINGLE) {
this->SettingsFile += this->ConfigSuffix;
}
this->SettingsFile += ".cmake";
}
return true;
}
@ -614,7 +487,7 @@ bool cmQtAutoGeneratorMocUic::SettingsFileWrite()
bool success = true;
// Only write if any setting changed
if (this->SettingsChanged()) {
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::GEN, "Writing settings file " +
cmQtAutoGen::Quoted(this->SettingsFile));
}
@ -644,7 +517,7 @@ bool cmQtAutoGeneratorMocUic::SettingsFileWrite()
return success;
}
bool cmQtAutoGeneratorMocUic::Process()
bool cmQtAutoGeneratorMocUic::Process(cmMakefile* makefile)
{
// the program goes through all .cpp files to see which moc files are
// included. It is not really interesting how the moc file is named, but
@ -654,6 +527,12 @@ bool cmQtAutoGeneratorMocUic::Process()
// moc file is included anywhere a moc_<filename>.cpp file is created and
// included in the mocs_compilation.cpp file.
if (!this->InitInfoFile(makefile)) {
return false;
}
// Read latest settings
this->SettingsFileRead(makefile);
// Create AUTOGEN include directory
{
std::string const incDirAbs = cmSystemTools::CollapseCombinedPath(
@ -690,6 +569,10 @@ bool cmQtAutoGeneratorMocUic::Process()
return false;
}
if (!this->SettingsFileWrite()) {
return false;
}
return true;
}
@ -701,7 +584,7 @@ bool cmQtAutoGeneratorMocUic::ParseSourceFile(std::string const& absFilename,
{
std::string contentText;
std::string error;
bool success = ReadFile(contentText, absFilename, &error);
bool success = this->FileRead(contentText, absFilename, &error);
if (success) {
if (!contentText.empty()) {
if (job.Moc) {
@ -729,7 +612,7 @@ bool cmQtAutoGeneratorMocUic::ParseHeaderFile(std::string const& absFilename,
{
std::string contentText;
std::string error;
bool success = ReadFile(contentText, absFilename, &error);
bool success = this->FileRead(contentText, absFilename, &error);
if (success) {
if (!contentText.empty()) {
if (job.Moc) {
@ -760,7 +643,7 @@ bool cmQtAutoGeneratorMocUic::ParsePostprocess()
if (!item->DependsValid) {
std::string content;
std::string error;
if (ReadFile(content, item->SourceFile, &error)) {
if (this->FileRead(content, item->SourceFile, &error)) {
this->MocFindDepends(item->SourceFile, content, item->Depends);
item->DependsValid = true;
} else {
@ -968,7 +851,7 @@ void cmQtAutoGeneratorMocUic::MocFindDepends(std::string const& absFilename,
std::string incFile;
if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
depends.insert(incFile);
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n " +
cmQtAutoGen::Quoted(absFilename) + "\n " +
cmQtAutoGen::Quoted(incFile));
@ -988,7 +871,7 @@ void cmQtAutoGeneratorMocUic::MocFindDepends(std::string const& absFilename,
bool cmQtAutoGeneratorMocUic::MocParseSourceContent(
std::string const& absFilename, std::string const& contentText)
{
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
}
@ -1227,7 +1110,7 @@ bool cmQtAutoGeneratorMocUic::MocParseSourceContent(
void cmQtAutoGeneratorMocUic::MocParseHeaderContent(
std::string const& absFilename, std::string const& contentText)
{
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
}
@ -1312,7 +1195,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateAll()
if (!this->MocPredefsCmd.empty()) {
if (this->MocSettingsChanged ||
!cmSystemTools::FileExists(this->MocPredefsFileAbs)) {
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel);
}
@ -1347,7 +1230,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateAll()
}
} else {
// Touch to update the time stamp
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::MOC,
"Touching moc_predefs " + this->MocPredefsFileRel);
}
@ -1398,7 +1281,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateAll()
if (this->FileDiffers(this->MocCompFileAbs, mocs)) {
// Actually write mocs compilation file
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating MOC compilation " + this->MocCompFileRel);
}
if (!this->FileWrite(cmQtAutoGen::MOC, this->MocCompFileAbs, mocs)) {
@ -1408,7 +1291,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateAll()
}
} else if (autoNameGenerated) {
// Only touch mocs compilation file
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::MOC,
"Touching mocs compilation " + this->MocCompFileRel);
}
@ -1433,7 +1316,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
bool generate = false;
std::string generateReason;
if (!generate && !cmSystemTools::FileExists(mocFileAbs.c_str())) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(mocFileAbs);
generateReason += " from its source file ";
@ -1443,7 +1326,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
generate = true;
}
if (!generate && this->MocSettingsChanged) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(mocFileAbs);
generateReason += " from ";
@ -1453,7 +1336,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
generate = true;
}
if (!generate && this->MocPredefsChanged) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(mocFileAbs);
generateReason += " from ";
@ -1465,7 +1348,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
if (!generate) {
std::string error;
if (FileIsOlderThan(mocFileAbs, mocJob.SourceFile, &error)) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(mocFileAbs);
generateReason += " because it's older than its source file ";
@ -1484,7 +1367,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
std::string error;
for (std::string const& depFile : mocJob.Depends) {
if (FileIsOlderThan(mocFileAbs, depFile, &error)) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(mocFileAbs);
generateReason += " from ";
@ -1505,7 +1388,7 @@ bool cmQtAutoGeneratorMocUic::MocGenerateFile(const MocJobAuto& mocJob,
if (generate) {
// Log
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating MOC source " + mocJob.BuildFileRel);
this->LogInfo(cmQtAutoGen::MOC, generateReason);
}
@ -1569,7 +1452,7 @@ bool cmQtAutoGeneratorMocUic::UicSkip(std::string const& absFilename) const
bool cmQtAutoGeneratorMocUic::UicParseContent(std::string const& absFilename,
std::string const& contentText)
{
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::UIC, "Checking: " + absFilename);
}
@ -1755,7 +1638,7 @@ bool cmQtAutoGeneratorMocUic::UicGenerateFile(const UicJob& uicJob)
bool generate = false;
std::string generateReason;
if (!generate && !cmSystemTools::FileExists(uicFileAbs.c_str())) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(uicFileAbs);
generateReason += " from its source file ";
@ -1765,7 +1648,7 @@ bool cmQtAutoGeneratorMocUic::UicGenerateFile(const UicJob& uicJob)
generate = true;
}
if (!generate && this->UicSettingsChanged) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(uicFileAbs);
generateReason += " from ";
@ -1777,7 +1660,7 @@ bool cmQtAutoGeneratorMocUic::UicGenerateFile(const UicJob& uicJob)
if (!generate) {
std::string error;
if (FileIsOlderThan(uicFileAbs, uicJob.SourceFile, &error)) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(uicFileAbs);
generateReason += " because it's older than its source file ";
@ -1793,7 +1676,7 @@ bool cmQtAutoGeneratorMocUic::UicGenerateFile(const UicJob& uicJob)
}
if (generate) {
// Log
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating UIC header " + uicJob.BuildFileRel);
this->LogInfo(cmQtAutoGen::UIC, generateReason);
}
@ -1839,191 +1722,6 @@ bool cmQtAutoGeneratorMocUic::UicGenerateFile(const UicJob& uicJob)
return success;
}
void cmQtAutoGeneratorMocUic::LogBold(std::string const& message) const
{
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, this->ColorOutput);
}
void cmQtAutoGeneratorMocUic::LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += ": ";
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorMocUic::LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += " warning:";
if (message.find('\n') == std::string::npos) {
// Single line message
msg.push_back(' ');
} else {
// Multi line message
msg.push_back('\n');
}
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorMocUic::LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string msg = " ";
msg += cmQtAutoGen::Quoted(filename);
msg.push_back('\n');
// Message
msg += message;
this->LogWarning(genType, msg);
}
void cmQtAutoGeneratorMocUic::LogError(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " error");
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorMocUic::LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string emsg = " ";
emsg += cmQtAutoGen::Quoted(filename);
emsg += '\n';
// Message
emsg += message;
this->LogError(genType, emsg);
}
void cmQtAutoGeneratorMocUic::LogCommandError(
cmQtAutoGen::Generator genType, std::string const& message,
std::vector<std::string> const& command, std::string const& output) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::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');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
/**
* @brief Generates the parent directory of the given file on demand
* @return True on success
*/
bool cmQtAutoGeneratorMocUic::MakeParentDirectory(
cmQtAutoGen::Generator genType, std::string const& filename) const
{
bool success = true;
std::string const dirName = cmSystemTools::GetFilenamePath(filename);
if (!dirName.empty()) {
if (!cmSystemTools::MakeDirectory(dirName)) {
this->LogFileError(genType, filename,
"Could not create parent directory");
success = false;
}
}
return success;
}
bool cmQtAutoGeneratorMocUic::FileDiffers(std::string const& filename,
std::string const& content)
{
bool differs = true;
{
std::string oldContents;
if (ReadFile(oldContents, filename)) {
differs = (oldContents != content);
}
}
return differs;
}
bool cmQtAutoGeneratorMocUic::FileWrite(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& content)
{
std::string error;
// Make sure the parent directory exists
if (this->MakeParentDirectory(genType, filename)) {
cmsys::ofstream outfile;
outfile.open(filename.c_str(),
(std::ios::out | std::ios::binary | std::ios::trunc));
if (outfile) {
outfile << content;
// Check for write errors
if (!outfile.good()) {
error = "File writing failed";
}
} else {
error = "Opening file for writing failed";
}
}
if (!error.empty()) {
this->LogFileError(genType, filename, error);
return false;
}
return true;
}
/**
* @brief Runs a command and returns true on success
* @return True on success
*/
bool cmQtAutoGeneratorMocUic::RunCommand(
std::vector<std::string> const& command, std::string& output) const
{
// Log command
if (this->Verbose) {
std::string qcmd = QuotedCommand(command);
qcmd.push_back('\n');
cmSystemTools::Stdout(qcmd.c_str(), qcmd.size());
}
// Execute command
int retVal = 0;
bool res = cmSystemTools::RunSingleCommand(
command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE);
return (res && (retVal == 0));
}
/**
* @brief Tries to find the header file to the given file base path by
* appending different header extensions

View File

@ -7,6 +7,7 @@
#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmsys/RegularExpression.hxx"
#include <map>
@ -17,12 +18,11 @@
class cmMakefile;
class cmQtAutoGeneratorMocUic
class cmQtAutoGeneratorMocUic : public cmQtAutoGenerator
{
CM_DISABLE_COPY(cmQtAutoGeneratorMocUic)
public:
cmQtAutoGeneratorMocUic();
bool Run(std::string const& targetDirectory, std::string const& config);
private:
// -- Types
@ -81,8 +81,7 @@ private:
};
// -- Initialization
bool InitInfoFile(cmMakefile* makefile, std::string const& targetDirectory,
std::string const& config);
bool InitInfoFile(cmMakefile* makefile);
// -- Settings file
void SettingsFileRead(cmMakefile* makefile);
@ -93,7 +92,7 @@ private:
}
// -- Central processing
bool Process();
bool Process(cmMakefile* makefile) override;
// -- Source parsing
bool ParseSourceFile(std::string const& absFilename, const SourceJob& job);
@ -136,45 +135,14 @@ private:
bool UicGenerateAll();
bool UicGenerateFile(const UicJob& uicJob);
// -- Log info
void LogBold(std::string const& message) const;
void LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const;
// -- Log warning
void LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
// -- Log error
void LogError(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
void LogCommandError(cmQtAutoGen::Generator genType,
std::string const& message,
std::vector<std::string> const& command,
std::string const& output) const;
// -- Utility
bool MakeParentDirectory(cmQtAutoGen::Generator genType,
std::string const& filename) const;
bool FileDiffers(std::string const& filename, std::string const& content);
bool FileWrite(cmQtAutoGen::Generator genType, std::string const& filename,
std::string const& content);
bool FindHeader(std::string& header, std::string const& testBasePath) const;
bool RunCommand(std::vector<std::string> const& command,
std::string& output) const;
// -- Meta
std::string InfoFile;
std::string ConfigSuffix;
cmQtAutoGen::MultiConfig MultiConfig;
// -- Settings
bool IncludeProjectDirsBefore;
bool Verbose;
bool ColorOutput;
std::string SettingsFile;
std::string SettingsStringMoc;
std::string SettingsStringUic;

View File

@ -3,146 +3,22 @@
#include "cmQtAutoGen.h"
#include "cmQtAutoGeneratorRcc.h"
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFilePathChecksum.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"
#if defined(__APPLE__)
#include <unistd.h>
#endif
// -- Static variables
static const char* SettingsKeyRcc = "ARCC_SETTINGS_HASH";
// -- Static functions
static std::string HeadLine(std::string const& title)
{
std::string head = title;
head += '\n';
head.append(head.size() - 1, '-');
head += '\n';
return head;
}
static std::string QuotedCommand(std::vector<std::string> const& command)
{
std::string res;
for (std::string const& item : command) {
if (!res.empty()) {
res.push_back(' ');
}
std::string const cesc = cmQtAutoGen::Quoted(item);
if (item.empty() || (cesc.size() > (item.size() + 2)) ||
(cesc.find(' ') != std::string::npos)) {
res += cesc;
} else {
res += item;
}
}
return res;
}
static bool ReadFile(std::string& content, std::string const& filename,
std::string* error = nullptr)
{
bool success = false;
if (cmSystemTools::FileExists(filename)) {
std::size_t const length = cmSystemTools::FileLength(filename);
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
if (ifs) {
content.resize(length);
ifs.read(&content.front(), content.size());
if (ifs) {
success = true;
} else {
content.clear();
if (error != nullptr) {
error->append("Reading from the file failed.");
}
}
} else if (error != nullptr) {
error->append("Opening the file for reading failed.");
}
} else if (error != nullptr) {
error->append("The file does not exist.");
}
return success;
}
/**
* @brief Tests if buildFile is older than sourceFile
* @return True if buildFile is older than sourceFile.
* False may indicate an error.
*/
static bool FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile,
std::string* error = nullptr)
{
int result = 0;
if (cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result)) {
return (result < 0);
}
if (error != nullptr) {
error->append(
"File modification time comparison failed for the files\n ");
error->append(cmQtAutoGen::Quoted(buildFile));
error->append("\nand\n ");
error->append(cmQtAutoGen::Quoted(sourceFile));
}
return false;
}
// -- Class methods
cmQtAutoGeneratorRcc::cmQtAutoGeneratorRcc()
: MultiConfig(cmQtAutoGen::WRAP)
, Verbose(cmSystemTools::HasEnv("VERBOSE"))
, ColorOutput(true)
, SettingsChanged(false)
{
{
std::string colorEnv;
cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
this->ColorOutput = cmSystemTools::IsOn(colorEnv.c_str());
}
}
}
bool cmQtAutoGeneratorRcc::Run(std::string const& infoFile,
std::string const& config)
{
// Info settings
this->InfoFile = infoFile;
this->InfoDir = cmSystemTools::GetFilenamePath(infoFile);
this->InfoConfig = config;
cmake cm(cmake::RoleScript);
cm.SetHomeOutputDirectory(this->InfoDir);
cm.SetHomeDirectory(this->InfoDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(this->InfoDir);
snapshot.GetDirectory().SetCurrentSource(this->InfoDir);
auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
gg.SetCurrentMakefile(makefile.get());
return this->Process(makefile.get());
}
bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile)
@ -161,7 +37,7 @@ bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile)
{
std::string keyConf = key;
keyConf += '_';
keyConf += this->InfoConfig;
keyConf += this->GetInfoConfig();
valueConf = makefile->GetDefinition(keyConf);
}
if (valueConf == nullptr) {
@ -177,8 +53,8 @@ bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile)
};
// -- Read info file
if (!makefile->ReadListFile(this->InfoFile.c_str())) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
if (!makefile->ReadListFile(this->GetInfoFile().c_str())) {
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"File processing failed");
return false;
}
@ -189,7 +65,7 @@ bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile)
this->ConfigSuffix = InfoGetConfig("ARCC_CONFIG_SUFFIX");
if (this->ConfigSuffix.empty()) {
this->ConfigSuffix = "_";
this->ConfigSuffix += this->InfoConfig;
this->ConfigSuffix += this->GetInfoConfig();
}
this->SettingsFile = InfoGetConfig("ARCC_SETTINGS_FILE");
@ -219,27 +95,27 @@ bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile)
// - Validity checks
if (this->SettingsFile.empty()) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"Settings file name missing");
return false;
}
if (this->AutogenBuildDir.empty()) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"Autogen build directory missing");
return false;
}
if (this->RccExecutable.empty()) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"rcc executable missing");
return false;
}
if (this->QrcFile.empty()) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"rcc input file missing");
return false;
}
if (this->RccFile.empty()) {
this->LogFileError(cmQtAutoGen::RCC, this->InfoFile,
this->LogFileError(cmQtAutoGen::RCC, this->GetInfoFile(),
"rcc output file missing");
return false;
}
@ -304,7 +180,7 @@ bool cmQtAutoGeneratorRcc::SettingsFileWrite()
bool success = true;
// Only write if any setting changed
if (this->SettingsChanged) {
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::RCC, "Writing settings file " +
cmQtAutoGen::Quoted(this->SettingsFile));
}
@ -392,7 +268,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
success = false;
}
if (success && !generate && !cmSystemTools::FileExists(rccFileAbs.c_str())) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(rccFileAbs);
generateReason += " from its source file ";
@ -402,7 +278,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
generate = true;
}
if (success && !generate && this->SettingsChanged) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(rccFileAbs);
generateReason += " from ";
@ -414,7 +290,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
if (success && !generate) {
std::string error;
if (FileIsOlderThan(rccFileAbs, this->QrcFile, &error)) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(rccFileAbs);
generateReason += " because it is older than ";
@ -457,7 +333,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
break;
}
if (FileIsOlderThan(rccFileAbs, resFile, &error)) {
if (this->Verbose) {
if (this->GetVerbose()) {
generateReason = "Generating ";
generateReason += cmQtAutoGen::Quoted(rccFileAbs);
generateReason += " from ";
@ -482,7 +358,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
// Regenerate on demand
if (generate) {
// Log
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating RCC source " + rccFileRel);
this->LogInfo(cmQtAutoGen::RCC, generateReason);
}
@ -531,7 +407,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
// Write content to file
if (this->FileDiffers(wrapperFileAbs, content)) {
// Write new wrapper file
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogBold("Generating RCC wrapper " + wrapperFileRel);
}
if (!this->FileWrite(cmQtAutoGen::RCC, wrapperFileAbs, content)) {
@ -541,7 +417,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
}
} else if (rccGenerated) {
// Just touch the wrapper file
if (this->Verbose) {
if (this->GetVerbose()) {
this->LogInfo(cmQtAutoGen::RCC,
"Touching RCC wrapper " + wrapperFileRel);
}
@ -551,188 +427,3 @@ bool cmQtAutoGeneratorRcc::RccGenerate()
return success;
}
void cmQtAutoGeneratorRcc::LogBold(std::string const& message) const
{
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, this->ColorOutput);
}
void cmQtAutoGeneratorRcc::LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += ": ";
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorRcc::LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg = cmQtAutoGen::GeneratorName(genType);
msg += " warning:";
if (message.find('\n') == std::string::npos) {
// Single line message
msg.push_back(' ');
} else {
// Multi line message
msg.push_back('\n');
}
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stdout(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorRcc::LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string msg = " ";
msg += cmQtAutoGen::Quoted(filename);
msg.push_back('\n');
// Message
msg += message;
this->LogWarning(genType, msg);
}
void cmQtAutoGeneratorRcc::LogError(cmQtAutoGen::Generator genType,
std::string const& message) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " error");
// Message
msg += message;
if (msg.back() != '\n') {
msg.push_back('\n');
}
msg.push_back('\n');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
void cmQtAutoGeneratorRcc::LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const
{
std::string emsg = " ";
emsg += cmQtAutoGen::Quoted(filename);
emsg += '\n';
// Message
emsg += message;
this->LogError(genType, emsg);
}
void cmQtAutoGeneratorRcc::LogCommandError(
cmQtAutoGen::Generator genType, std::string const& message,
std::vector<std::string> const& command, std::string const& output) const
{
std::string msg;
msg.push_back('\n');
msg += HeadLine(cmQtAutoGen::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');
cmSystemTools::Stderr(msg.c_str(), msg.size());
}
/**
* @brief Generates the parent directory of the given file on demand
* @return True on success
*/
bool cmQtAutoGeneratorRcc::MakeParentDirectory(
cmQtAutoGen::Generator genType, std::string const& filename) const
{
bool success = true;
std::string const dirName = cmSystemTools::GetFilenamePath(filename);
if (!dirName.empty()) {
if (!cmSystemTools::MakeDirectory(dirName)) {
this->LogFileError(genType, filename,
"Could not create parent directory");
success = false;
}
}
return success;
}
bool cmQtAutoGeneratorRcc::FileDiffers(std::string const& filename,
std::string const& content)
{
bool differs = true;
{
std::string oldContents;
if (ReadFile(oldContents, filename)) {
differs = (oldContents != content);
}
}
return differs;
}
bool cmQtAutoGeneratorRcc::FileWrite(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& content)
{
std::string error;
// Make sure the parent directory exists
if (this->MakeParentDirectory(genType, filename)) {
cmsys::ofstream outfile;
outfile.open(filename.c_str(),
(std::ios::out | std::ios::binary | std::ios::trunc));
if (outfile) {
outfile << content;
// Check for write errors
if (!outfile.good()) {
error = "File writing failed";
}
} else {
error = "Opening file for writing failed";
}
}
if (!error.empty()) {
this->LogFileError(genType, filename, error);
return false;
}
return true;
}
/**
* @brief Runs a command and returns true on success
* @return True on success
*/
bool cmQtAutoGeneratorRcc::RunCommand(std::vector<std::string> const& command,
std::string& output) const
{
// Log command
if (this->Verbose) {
std::string qcmd = QuotedCommand(command);
qcmd.push_back('\n');
cmSystemTools::Stdout(qcmd.c_str(), qcmd.size());
}
// Execute command
int retVal = 0;
bool res = cmSystemTools::RunSingleCommand(
command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE);
return (res && (retVal == 0));
}

View File

@ -7,18 +7,18 @@
#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include <string>
#include <vector>
class cmMakefile;
class cmQtAutoGeneratorRcc
class cmQtAutoGeneratorRcc : public cmQtAutoGenerator
{
CM_DISABLE_COPY(cmQtAutoGeneratorRcc)
public:
cmQtAutoGeneratorRcc();
bool Run(std::string const& infoFile, std::string const& config);
private:
// -- Initialization & settings
@ -26,47 +26,13 @@ private:
void SettingsFileRead(cmMakefile* makefile);
bool SettingsFileWrite();
// -- Central processing
bool Process(cmMakefile* makefile);
bool Process(cmMakefile* makefile) override;
bool RccGenerate();
// -- Log info
void LogBold(std::string const& message) const;
void LogInfo(cmQtAutoGen::Generator genType,
std::string const& message) const;
// -- Log warning
void LogWarning(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileWarning(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
// -- Log error
void LogError(cmQtAutoGen::Generator genType,
std::string const& message) const;
void LogFileError(cmQtAutoGen::Generator genType,
std::string const& filename,
std::string const& message) const;
void LogCommandError(cmQtAutoGen::Generator genType,
std::string const& message,
std::vector<std::string> const& command,
std::string const& output) const;
// -- Utility
bool MakeParentDirectory(cmQtAutoGen::Generator genType,
std::string const& filename) const;
bool FileDiffers(std::string const& filename, std::string const& content);
bool FileWrite(cmQtAutoGen::Generator genType, std::string const& filename,
std::string const& content);
bool RunCommand(std::vector<std::string> const& command,
std::string& output) const;
// -- Info settings
std::string InfoFile;
std::string InfoDir;
std::string InfoConfig;
// -- Config settings
std::string ConfigSuffix;
cmQtAutoGen::MultiConfig MultiConfig;
// -- Settings
bool Verbose;
bool ColorOutput;
bool SettingsChanged;
std::string SettingsFile;
std::string SettingsString;