mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-29 04:09:35 +03:00
Autogen: Use JSON instead of CMake script for info files
We used to store information for the _autogen target in a CMake script file AutogenInfo.cmake, which was imported by a temporary cmake instance in the _autogen target. This introduced the overhead of creating a temporary cmake instance and inherited the limitations of the CMake language which only supports lists. This patch introduces JSON files to pass information to AUTORCC and autogen_ targets. JSON files are more flexible for passing data, e.g. they support nested lists. The patch has the side effects that - AutogenInfo.cmake is renamed to AutogenInfo.json - AutogenOldSettings.txt is renamed to AutogenUsed.txt - RCC<qrcBaseName><checksum>Info.cmake is renamed to AutoRcc_<qrcBaseName>_<checksum>_Info.json - RCC<qrcBaseName><checksum>.lock is renamed to AutoRcc_<qrcBaseName>_<checksum>_Lock.lock - RCC<qrcBaseName><checksum>Settings.txt is renamed to AutoRcc_<qrcBaseName>_<checksum>_Used.txt
This commit is contained in:
committed by
Brad King
parent
881e3cfbf9
commit
d867e05892
+10
-1
@@ -72,7 +72,6 @@ void MergeOptions(std::vector<std::string>& baseOpts,
|
||||
// - Class definitions
|
||||
|
||||
unsigned int const cmQtAutoGen::ParallelMax = 64;
|
||||
std::string const cmQtAutoGen::ListSep = "<<<S>>>";
|
||||
|
||||
cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
|
||||
{
|
||||
@@ -162,6 +161,16 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string cmQtAutoGen::FileNameWithoutLastExtension(cm::string_view filename)
|
||||
{
|
||||
auto slashPos = filename.rfind('/');
|
||||
if (slashPos != cm::string_view::npos) {
|
||||
filename.remove_prefix(slashPos + 1);
|
||||
}
|
||||
auto dotPos = filename.rfind('.');
|
||||
return std::string(filename.substr(0, dotPos));
|
||||
}
|
||||
|
||||
std::string cmQtAutoGen::ParentDir(cm::string_view filename)
|
||||
{
|
||||
auto slashPos = filename.rfind('/');
|
||||
|
||||
@@ -62,8 +62,6 @@ public:
|
||||
RCC // AUTORCC
|
||||
};
|
||||
|
||||
/// @brief Nested lists separator
|
||||
static std::string const ListSep;
|
||||
/// @brief Maximum number of parallel threads/processes in a generator
|
||||
static unsigned int const ParallelMax;
|
||||
|
||||
@@ -81,6 +79,9 @@ public:
|
||||
|
||||
static std::string QuotedCommand(std::vector<std::string> const& command);
|
||||
|
||||
/// @brief Returns the file name without path and extension (thread safe)
|
||||
static std::string FileNameWithoutLastExtension(cm::string_view filename);
|
||||
|
||||
/// @brief Returns the parent directory of the file (thread safe)
|
||||
static std::string ParentDir(cm::string_view filename);
|
||||
|
||||
|
||||
+454
-392
@@ -8,7 +8,7 @@
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmCustomCommand.h"
|
||||
#include "cmCustomCommandLines.h"
|
||||
#include "cmFilePathChecksum.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmSourceFileLocationKind.h"
|
||||
@@ -27,6 +26,8 @@
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cm_jsoncpp_value.h"
|
||||
#include "cm_jsoncpp_writer.h"
|
||||
#include "cmake.h"
|
||||
#include "cmsys/SystemInformation.hxx"
|
||||
|
||||
@@ -34,6 +35,7 @@
|
||||
#include <deque>
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
@@ -41,6 +43,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <cm/algorithm>
|
||||
#include <cm/iterator>
|
||||
#include <cm/memory>
|
||||
|
||||
namespace {
|
||||
@@ -157,100 +160,135 @@ std::vector<std::string> SearchPathSanitizer::operator()(
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Writes a CMake info file. */
|
||||
class InfoWriter
|
||||
{
|
||||
public:
|
||||
// -- Single value
|
||||
void Set(std::string const& key, std::string const& value)
|
||||
{
|
||||
Value_[key] = value;
|
||||
}
|
||||
void SetConfig(std::string const& key,
|
||||
cmQtAutoGenInitializer::ConfigString const& cfgStr);
|
||||
void SetBool(std::string const& key, bool value) { Value_[key] = value; }
|
||||
void SetUInt(std::string const& key, unsigned int value)
|
||||
{
|
||||
Value_[key] = value;
|
||||
}
|
||||
|
||||
// -- Array utility
|
||||
template <typename CONT>
|
||||
static bool MakeArray(Json::Value& jval, CONT const& container);
|
||||
|
||||
template <typename CONT>
|
||||
static void MakeStringArray(Json::Value& jval, CONT const& container);
|
||||
|
||||
// -- Array value
|
||||
template <typename CONT>
|
||||
void SetArray(std::string const& key, CONT const& container);
|
||||
template <typename CONT>
|
||||
void SetConfigArray(
|
||||
std::string const& key,
|
||||
cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr);
|
||||
|
||||
// -- Array of arrays
|
||||
template <typename CONT, typename FUNC>
|
||||
void SetArrayArray(std::string const& key, CONT const& container, FUNC func);
|
||||
|
||||
// -- Save to json file
|
||||
bool Save(std::string const& filename);
|
||||
|
||||
private:
|
||||
Json::Value Value_;
|
||||
};
|
||||
|
||||
void InfoWriter::SetConfig(std::string const& key,
|
||||
cmQtAutoGenInitializer::ConfigString const& cfgStr)
|
||||
{
|
||||
Set(key, cfgStr.Default);
|
||||
for (auto const& item : cfgStr.Config) {
|
||||
Set(cmStrCat(key, '_', item.first), item.second);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CONT>
|
||||
bool InfoWriter::MakeArray(Json::Value& jval, CONT const& container)
|
||||
{
|
||||
jval = Json::arrayValue;
|
||||
std::size_t const listSize = cm::size(container);
|
||||
if (listSize == 0) {
|
||||
return false;
|
||||
}
|
||||
jval.resize(static_cast<unsigned int>(listSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CONT>
|
||||
void InfoWriter::MakeStringArray(Json::Value& jval, CONT const& container)
|
||||
{
|
||||
if (MakeArray(jval, container)) {
|
||||
Json::ArrayIndex ii = 0;
|
||||
for (std::string const& item : container) {
|
||||
jval[ii++] = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CONT>
|
||||
void InfoWriter::SetArray(std::string const& key, CONT const& container)
|
||||
{
|
||||
MakeStringArray(Value_[key], container);
|
||||
}
|
||||
|
||||
template <typename CONT, typename FUNC>
|
||||
void InfoWriter::SetArrayArray(std::string const& key, CONT const& container,
|
||||
FUNC func)
|
||||
{
|
||||
Json::Value& jval = Value_[key];
|
||||
if (MakeArray(jval, container)) {
|
||||
Json::ArrayIndex ii = 0;
|
||||
for (auto const& citem : container) {
|
||||
Json::Value& aval = jval[ii++];
|
||||
aval = Json::arrayValue;
|
||||
func(aval, citem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CONT>
|
||||
void InfoWriter::SetConfigArray(
|
||||
std::string const& key,
|
||||
cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr)
|
||||
{
|
||||
SetArray(key, cfgStr.Default);
|
||||
for (auto const& item : cfgStr.Config) {
|
||||
SetArray(cmStrCat(key, '_', item.first), item.second);
|
||||
}
|
||||
}
|
||||
|
||||
bool InfoWriter::Save(std::string const& filename)
|
||||
{
|
||||
cmGeneratedFileStream fileStream;
|
||||
fileStream.SetCopyIfDifferent(true);
|
||||
fileStream.Open(filename, false, true);
|
||||
if (!fileStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::StyledStreamWriter jsonWriter;
|
||||
try {
|
||||
jsonWriter.write(fileStream, Value_);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileStream.Close();
|
||||
}
|
||||
|
||||
} // End of unnamed namespace
|
||||
|
||||
cmQtAutoGenInitializer::InfoWriter::InfoWriter(std::string const& filename)
|
||||
{
|
||||
Ofs_.SetCopyIfDifferent(true);
|
||||
Ofs_.Open(filename, false, true);
|
||||
}
|
||||
|
||||
template <class IT>
|
||||
std::string cmQtAutoGenInitializer::InfoWriter::ListJoin(IT it_begin,
|
||||
IT it_end)
|
||||
{
|
||||
std::string res;
|
||||
for (IT it = it_begin; it != it_end; ++it) {
|
||||
if (it != it_begin) {
|
||||
res += ';';
|
||||
}
|
||||
for (const char* c = it->c_str(); *c; ++c) {
|
||||
if (*c == '"') {
|
||||
// Escape the double quote to avoid ending the argument.
|
||||
res += "\\\"";
|
||||
} else if (*c == '$') {
|
||||
// Escape the dollar to avoid expanding variables.
|
||||
res += "\\$";
|
||||
} else if (*c == '\\') {
|
||||
// Escape the backslash to avoid other escapes.
|
||||
res += "\\\\";
|
||||
} else if (*c == ';') {
|
||||
// Escape the semicolon to avoid list expansion.
|
||||
res += "\\;";
|
||||
} else {
|
||||
// Other characters will be parsed correctly.
|
||||
res += *c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey(
|
||||
cm::string_view key, std::string const& config)
|
||||
{
|
||||
return cmStrCat(key, "_", config);
|
||||
}
|
||||
|
||||
void cmQtAutoGenInitializer::InfoWriter::Write(cm::string_view key,
|
||||
std::string const& value)
|
||||
{
|
||||
Ofs_ << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value)
|
||||
<< ")\n";
|
||||
};
|
||||
|
||||
void cmQtAutoGenInitializer::InfoWriter::WriteUInt(cm::string_view key,
|
||||
unsigned int value)
|
||||
{
|
||||
Ofs_ << "set(" << key << " " << value << ")\n";
|
||||
};
|
||||
|
||||
template <class C>
|
||||
void cmQtAutoGenInitializer::InfoWriter::WriteStrings(cm::string_view key,
|
||||
C const& container)
|
||||
{
|
||||
Ofs_ << "set(" << key << " \""
|
||||
<< ListJoin(container.begin(), container.end()) << "\")\n";
|
||||
}
|
||||
|
||||
void cmQtAutoGenInitializer::InfoWriter::WriteConfig(
|
||||
cm::string_view key, std::map<std::string, std::string> const& map)
|
||||
{
|
||||
for (auto const& item : map) {
|
||||
Write(ConfigKey(key, item.first), item.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <class C>
|
||||
void cmQtAutoGenInitializer::InfoWriter::WriteConfigStrings(
|
||||
cm::string_view key, std::map<std::string, C> const& map)
|
||||
{
|
||||
for (auto const& item : map) {
|
||||
WriteStrings(ConfigKey(key, item.first), item.second);
|
||||
}
|
||||
}
|
||||
|
||||
void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists(
|
||||
cm::string_view key, std::vector<std::vector<std::string>> const& lists)
|
||||
{
|
||||
std::vector<std::string> seplist;
|
||||
seplist.reserve(lists.size());
|
||||
for (std::vector<std::string> const& list : lists) {
|
||||
seplist.push_back(cmStrCat("{", ListJoin(list.begin(), list.end()), "}"));
|
||||
}
|
||||
Write(key, cmJoin(seplist, cmQtAutoGen::ListSep));
|
||||
};
|
||||
|
||||
cmQtAutoGenInitializer::cmQtAutoGenInitializer(
|
||||
cmQtAutoGenGlobalInitializer* globalInitializer,
|
||||
cmGeneratorTarget* genTarget, IntegerVersion const& qtVersion,
|
||||
@@ -261,6 +299,7 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer(
|
||||
, GlobalGen(genTarget->GetGlobalGenerator())
|
||||
, LocalGen(genTarget->GetLocalGenerator())
|
||||
, Makefile(genTarget->Makefile)
|
||||
, PathCheckSum(genTarget->Makefile)
|
||||
, QtVersion(qtVersion)
|
||||
{
|
||||
AutogenTarget.GlobalTarget = globalAutogenTarget;
|
||||
@@ -280,12 +319,20 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
}
|
||||
|
||||
// Verbosity
|
||||
this->Verbosity = this->Makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
|
||||
if (!this->Verbosity.empty()) {
|
||||
unsigned long iVerb = 0;
|
||||
if (!cmStrToULong(this->Verbosity, &iVerb)) {
|
||||
// Non numeric verbosity
|
||||
this->Verbosity = cmIsOn(this->Verbosity) ? "1" : "0";
|
||||
{
|
||||
std::string def =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
|
||||
if (!def.empty()) {
|
||||
unsigned long iVerb = 0;
|
||||
if (cmStrToULong(def, &iVerb)) {
|
||||
// Numeric verbosity
|
||||
this->Verbosity = static_cast<unsigned int>(iVerb);
|
||||
} else {
|
||||
// Non numeric verbosity
|
||||
if (cmIsOn(def)) {
|
||||
this->Verbosity = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,15 +399,9 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
cmSystemTools::ConvertToUnixSlashes(this->Dir.Work);
|
||||
|
||||
// Include directory
|
||||
this->Dir.Include = cmStrCat(this->Dir.Build, "/include");
|
||||
// Per config include directories
|
||||
if (this->MultiConfig) {
|
||||
for (std::string const& cfg : this->ConfigsList) {
|
||||
std::string& dir = this->Dir.ConfigInclude[cfg];
|
||||
dir = cmStrCat(this->Dir.Build, "/include_", cfg);
|
||||
}
|
||||
}
|
||||
this->Dir.IncludeGenExp = this->Dir.Include;
|
||||
ConfigFileNames(this->Dir.Include, cmStrCat(this->Dir.Build, "/include"),
|
||||
"");
|
||||
this->Dir.IncludeGenExp = this->Dir.Include.Default;
|
||||
if (this->MultiConfig) {
|
||||
this->Dir.IncludeGenExp += "_$<CONFIG>";
|
||||
}
|
||||
@@ -383,36 +424,31 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
cmStrCat(this->GenTarget->GetName(), "_autogen");
|
||||
|
||||
// Autogen target parallel processing
|
||||
this->AutogenTarget.Parallel =
|
||||
this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
|
||||
if (this->AutogenTarget.Parallel.empty() ||
|
||||
(this->AutogenTarget.Parallel == "AUTO")) {
|
||||
// Autodetect number of CPUs
|
||||
this->AutogenTarget.Parallel = std::to_string(GetParallelCPUCount());
|
||||
{
|
||||
std::string prop = this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
|
||||
if (prop.empty() || (prop == "AUTO")) {
|
||||
// Autodetect number of CPUs
|
||||
this->AutogenTarget.Parallel = GetParallelCPUCount();
|
||||
} else {
|
||||
this->AutogenTarget.Parallel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Autogen target info and settings files
|
||||
{
|
||||
// Info file
|
||||
this->AutogenTarget.InfoFile =
|
||||
cmStrCat(this->Dir.Info, "/AutogenInfo.cmake");
|
||||
cmStrCat(this->Dir.Info, "/AutogenInfo.json");
|
||||
|
||||
this->AutogenTarget.SettingsFile =
|
||||
cmStrCat(this->Dir.Info, "/AutogenOldSettings.txt");
|
||||
// Used settings file
|
||||
ConfigFileNames(this->AutogenTarget.SettingsFile,
|
||||
cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt");
|
||||
ConfigFileClean(this->AutogenTarget.SettingsFile);
|
||||
|
||||
if (this->MultiConfig) {
|
||||
for (std::string const& cfg : this->ConfigsList) {
|
||||
std::string& filename = this->AutogenTarget.ConfigSettingsFile[cfg];
|
||||
filename =
|
||||
AppendFilenameSuffix(this->AutogenTarget.SettingsFile, "_" + cfg);
|
||||
this->AddCleanFile(filename);
|
||||
}
|
||||
} else {
|
||||
this->AddCleanFile(this->AutogenTarget.SettingsFile);
|
||||
}
|
||||
|
||||
this->AutogenTarget.ParseCacheFile =
|
||||
cmStrCat(this->Dir.Info, "/ParseCache.txt");
|
||||
this->AddCleanFile(this->AutogenTarget.ParseCacheFile);
|
||||
// Parse cache file
|
||||
ConfigFileNames(this->AutogenTarget.ParseCacheFile,
|
||||
cmStrCat(this->Dir.Info, "/ParseCache"), ".txt");
|
||||
ConfigFileClean(this->AutogenTarget.ParseCacheFile);
|
||||
}
|
||||
|
||||
// Autogen target: Compute user defined dependencies
|
||||
@@ -435,9 +471,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
}
|
||||
}
|
||||
|
||||
// CMAKE_AUTOMOC_RELAXED_MODE deprecation warning
|
||||
if (this->Moc.Enabled) {
|
||||
// Path prefix
|
||||
if (cmIsOn(this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"))) {
|
||||
this->Moc.PathPrefix = true;
|
||||
}
|
||||
|
||||
// CMAKE_AUTOMOC_RELAXED_MODE
|
||||
if (this->Makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
|
||||
this->Moc.RelaxedMode = true;
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
|
||||
@@ -445,6 +487,32 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
"disabling it and converting the target ",
|
||||
this->GenTarget->GetName(), " to regular mode."));
|
||||
}
|
||||
|
||||
// Options
|
||||
cmExpandList(this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS"),
|
||||
this->Moc.Options);
|
||||
// Filters
|
||||
cmExpandList(this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"),
|
||||
this->Moc.MacroNames);
|
||||
{
|
||||
auto filterList = cmExpandedList(
|
||||
this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
|
||||
if ((filterList.size() % 2) != 0) {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("AutoMoc: AUTOMOC_DEPEND_FILTERS predefs size ",
|
||||
filterList.size(), " is not a multiple of 2."));
|
||||
return false;
|
||||
}
|
||||
this->Moc.DependFilters.reserve(1 + (filterList.size() / 2));
|
||||
this->Moc.DependFilters.emplace_back(
|
||||
"Q_PLUGIN_METADATA",
|
||||
"[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
|
||||
"[^\\)]*FILE[ \t]*\"([^\"]+)\"");
|
||||
for (std::size_t ii = 0; ii != filterList.size(); ii += 2) {
|
||||
this->Moc.DependFilters.emplace_back(filterList[ii],
|
||||
filterList[ii + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,20 +547,27 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
bool cmQtAutoGenInitializer::InitMoc()
|
||||
{
|
||||
// Mocs compilation file
|
||||
this->Moc.MocsCompilation =
|
||||
this->Moc.CompilationFile =
|
||||
cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
|
||||
|
||||
// Moc predefs command
|
||||
// Moc predefs
|
||||
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
|
||||
(this->QtVersion >= IntegerVersion(5, 8))) {
|
||||
this->Moc.PredefsCmd = this->Makefile->GetSafeDefinition(
|
||||
"CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
|
||||
// Command
|
||||
cmExpandList(this->Makefile->GetSafeDefinition(
|
||||
"CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"),
|
||||
this->Moc.PredefsCmd);
|
||||
// Header
|
||||
if (!this->Moc.PredefsCmd.empty()) {
|
||||
ConfigFileNames(this->Moc.PredefsFile,
|
||||
cmStrCat(this->Dir.Build, "/moc_predefs"), ".h");
|
||||
}
|
||||
}
|
||||
|
||||
// Moc includes
|
||||
{
|
||||
SearchPathSanitizer sanitizer(this->Makefile);
|
||||
auto GetIncludeDirs =
|
||||
auto getDirs =
|
||||
[this, &sanitizer](std::string const& cfg) -> std::vector<std::string> {
|
||||
// Get the include dirs for this target, without stripping the implicit
|
||||
// include dirs off, see issue #13667.
|
||||
@@ -504,22 +579,22 @@ bool cmQtAutoGenInitializer::InitMoc()
|
||||
};
|
||||
|
||||
// Default configuration include directories
|
||||
this->Moc.Includes = GetIncludeDirs(this->ConfigDefault);
|
||||
this->Moc.Includes.Default = getDirs(this->ConfigDefault);
|
||||
// Other configuration settings
|
||||
if (this->MultiConfig) {
|
||||
for (std::string const& cfg : this->ConfigsList) {
|
||||
std::vector<std::string> dirs = GetIncludeDirs(cfg);
|
||||
if (dirs != this->Moc.Includes) {
|
||||
this->Moc.ConfigIncludes[cfg] = std::move(dirs);
|
||||
std::vector<std::string> dirs = getDirs(cfg);
|
||||
if (dirs == this->Moc.Includes.Default) {
|
||||
continue;
|
||||
}
|
||||
this->Moc.Includes.Config[cfg] = std::move(dirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Moc compile definitions
|
||||
{
|
||||
auto GetCompileDefinitions =
|
||||
[this](std::string const& cfg) -> std::set<std::string> {
|
||||
auto getDefs = [this](std::string const& cfg) -> std::set<std::string> {
|
||||
std::set<std::string> defines;
|
||||
this->LocalGen->GetTargetDefines(this->GenTarget, cfg, "CXX", defines);
|
||||
#ifdef _WIN32
|
||||
@@ -532,14 +607,15 @@ bool cmQtAutoGenInitializer::InitMoc()
|
||||
};
|
||||
|
||||
// Default configuration defines
|
||||
this->Moc.Defines = GetCompileDefinitions(this->ConfigDefault);
|
||||
this->Moc.Defines.Default = getDefs(this->ConfigDefault);
|
||||
// Other configuration defines
|
||||
if (this->MultiConfig) {
|
||||
for (std::string const& cfg : this->ConfigsList) {
|
||||
std::set<std::string> defines = GetCompileDefinitions(cfg);
|
||||
if (defines != this->Moc.Defines) {
|
||||
this->Moc.ConfigDefines[cfg] = std::move(defines);
|
||||
std::set<std::string> defines = getDefs(cfg);
|
||||
if (defines == this->Moc.Defines.Default) {
|
||||
continue;
|
||||
}
|
||||
this->Moc.Defines.Config[cfg] = std::move(defines);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -572,23 +648,22 @@ bool cmQtAutoGenInitializer::InitUic()
|
||||
}
|
||||
// Uic target options
|
||||
{
|
||||
auto UicGetOpts =
|
||||
[this](std::string const& cfg) -> std::vector<std::string> {
|
||||
auto getOpts = [this](std::string const& cfg) -> std::vector<std::string> {
|
||||
std::vector<std::string> opts;
|
||||
this->GenTarget->GetAutoUicOptions(opts, cfg);
|
||||
return opts;
|
||||
};
|
||||
|
||||
// Default settings
|
||||
this->Uic.Options = UicGetOpts(this->ConfigDefault);
|
||||
|
||||
// Configuration specific settings
|
||||
// Default options
|
||||
this->Uic.Options.Default = getOpts(this->ConfigDefault);
|
||||
// Configuration specific options
|
||||
if (this->MultiConfig) {
|
||||
for (std::string const& cfg : this->ConfigsList) {
|
||||
std::vector<std::string> options = UicGetOpts(cfg);
|
||||
if (options != this->Uic.Options) {
|
||||
this->Uic.ConfigOptions[cfg] = std::move(options);
|
||||
std::vector<std::string> options = getOpts(cfg);
|
||||
if (options == this->Uic.Options.Default) {
|
||||
continue;
|
||||
}
|
||||
this->Uic.Options.Config[cfg] = std::move(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -822,8 +897,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
// Check if the .ui file has uic options
|
||||
std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS);
|
||||
if (!uicOpts.empty()) {
|
||||
this->Uic.FileFiles.push_back(fullPath);
|
||||
this->Uic.FileOptions.push_back(cmExpandedList(uicOpts));
|
||||
this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts));
|
||||
}
|
||||
} else {
|
||||
// Register skipped .ui file
|
||||
@@ -887,31 +961,17 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
}
|
||||
}
|
||||
// Path checksum and file names
|
||||
{
|
||||
cmFilePathChecksum const fpathCheckSum(this->Makefile);
|
||||
for (Qrc& qrc : this->Rcc.Qrcs) {
|
||||
// Path checksum
|
||||
qrc.QrcPathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
|
||||
// Output file name
|
||||
qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
|
||||
"/qrc_", qrc.QrcName, ".cpp");
|
||||
{
|
||||
cm::string_view const baseSuffix = qrc.Unique
|
||||
? cm::string_view()
|
||||
: cm::string_view(qrc.QrcPathChecksum);
|
||||
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] =
|
||||
AppendFilenameSuffix(qrc.SettingsFile, "_" + cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Qrc& qrc : this->Rcc.Qrcs) {
|
||||
// Path checksum
|
||||
qrc.QrcPathChecksum = this->PathCheckSum.getPart(qrc.QrcFile);
|
||||
// Output file name
|
||||
qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
|
||||
"/qrc_", qrc.QrcName, ".cpp");
|
||||
std::string const base = cmStrCat(this->Dir.Info, "/AutoRcc_",
|
||||
qrc.QrcName, '_', qrc.QrcPathChecksum);
|
||||
qrc.LockFile = cmStrCat(base, "_Lock.lock");
|
||||
qrc.InfoFile = cmStrCat(base, "_Info.json");
|
||||
ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt");
|
||||
}
|
||||
// rcc options
|
||||
for (Qrc& qrc : this->Rcc.Qrcs) {
|
||||
@@ -959,8 +1019,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
// Files provided by the autogen target
|
||||
std::vector<std::string> autogenProvides;
|
||||
if (this->Moc.Enabled) {
|
||||
this->AddGeneratedSource(this->Moc.MocsCompilation, this->Moc, true);
|
||||
autogenProvides.push_back(this->Moc.MocsCompilation);
|
||||
this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
|
||||
autogenProvides.push_back(this->Moc.CompilationFile);
|
||||
}
|
||||
|
||||
// Compose target comment
|
||||
@@ -1214,229 +1274,185 @@ bool cmQtAutoGenInitializer::SetupCustomTargets()
|
||||
|
||||
bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
|
||||
{
|
||||
InfoWriter ofs(this->AutogenTarget.InfoFile);
|
||||
if (ofs) {
|
||||
// Utility lambdas
|
||||
auto MfDef = [this](const char* key) {
|
||||
return this->Makefile->GetSafeDefinition(key);
|
||||
};
|
||||
// Utility lambdas
|
||||
auto MfDef = [this](std::string const& key) {
|
||||
return this->Makefile->GetSafeDefinition(key);
|
||||
};
|
||||
|
||||
// Write common settings
|
||||
ofs.Write("# Meta\n");
|
||||
ofs.Write("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE");
|
||||
ofs.Write("AM_PARALLEL", this->AutogenTarget.Parallel);
|
||||
ofs.Write("AM_VERBOSITY", this->Verbosity);
|
||||
// Filtered headers and sources
|
||||
std::set<std::string> moc_skip;
|
||||
std::set<std::string> uic_skip;
|
||||
std::vector<MUFile const*> headers;
|
||||
std::vector<MUFile const*> sources;
|
||||
|
||||
ofs.Write("# Directories\n");
|
||||
ofs.Write("AM_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
|
||||
ofs.Write("AM_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
|
||||
ofs.Write("AM_CMAKE_CURRENT_SOURCE_DIR",
|
||||
MfDef("CMAKE_CURRENT_SOURCE_DIR"));
|
||||
ofs.Write("AM_CMAKE_CURRENT_BINARY_DIR",
|
||||
MfDef("CMAKE_CURRENT_BINARY_DIR"));
|
||||
ofs.Write("AM_BUILD_DIR", this->Dir.Build);
|
||||
ofs.Write("AM_INCLUDE_DIR", this->Dir.Include);
|
||||
ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude);
|
||||
|
||||
std::vector<std::string> headers;
|
||||
std::vector<std::string> headersFlags;
|
||||
std::vector<std::string> headersBuildPaths;
|
||||
std::vector<std::string> sources;
|
||||
std::vector<std::string> sourcesFlags;
|
||||
std::set<std::string> moc_skip;
|
||||
std::set<std::string> uic_skip;
|
||||
|
||||
// Filter headers
|
||||
{
|
||||
auto headerCount = this->AutogenTarget.Headers.size();
|
||||
headers.reserve(headerCount);
|
||||
headersFlags.reserve(headerCount);
|
||||
|
||||
std::vector<MUFile const*> sortedHeaders;
|
||||
{
|
||||
sortedHeaders.reserve(headerCount);
|
||||
for (auto const& pair : this->AutogenTarget.Headers) {
|
||||
sortedHeaders.emplace_back(pair.second.get());
|
||||
}
|
||||
std::sort(sortedHeaders.begin(), sortedHeaders.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->FullPath < b->FullPath);
|
||||
});
|
||||
// Filter headers
|
||||
{
|
||||
headers.reserve(this->AutogenTarget.Headers.size());
|
||||
for (auto const& pair : this->AutogenTarget.Headers) {
|
||||
MUFile const* const muf = pair.second.get();
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (MUFile const* const muf : sortedHeaders) {
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
headers.emplace_back(muf->FullPath);
|
||||
headersFlags.emplace_back(
|
||||
cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
headers.emplace_back(muf);
|
||||
}
|
||||
}
|
||||
// Header build paths
|
||||
{
|
||||
cmFilePathChecksum const fpathCheckSum(this->Makefile);
|
||||
std::unordered_set<std::string> emitted;
|
||||
for (std::string const& hdr : headers) {
|
||||
std::string const basePath =
|
||||
cmStrCat(fpathCheckSum.getPart(hdr), "/moc_",
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(hdr));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter sources
|
||||
{
|
||||
auto sourcesCount = this->AutogenTarget.Sources.size();
|
||||
sources.reserve(sourcesCount);
|
||||
sourcesFlags.reserve(sourcesCount);
|
||||
|
||||
std::vector<MUFile const*> sorted;
|
||||
sorted.reserve(sourcesCount);
|
||||
for (auto const& pair : this->AutogenTarget.Sources) {
|
||||
sorted.emplace_back(pair.second.get());
|
||||
}
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->FullPath < b->FullPath);
|
||||
});
|
||||
|
||||
for (MUFile const* const muf : sorted) {
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
sources.emplace_back(muf->FullPath);
|
||||
sourcesFlags.emplace_back(
|
||||
cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ofs.Write("# Qt\n");
|
||||
ofs.WriteUInt("AM_QT_VERSION_MAJOR", this->QtVersion.Major);
|
||||
ofs.Write("AM_QT_MOC_EXECUTABLE", this->Moc.Executable);
|
||||
ofs.Write("AM_QT_UIC_EXECUTABLE", this->Uic.Executable);
|
||||
|
||||
ofs.Write("# Files\n");
|
||||
ofs.Write("AM_CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
|
||||
ofs.Write("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile);
|
||||
ofs.WriteConfig("AM_SETTINGS_FILE",
|
||||
this->AutogenTarget.ConfigSettingsFile);
|
||||
ofs.Write("AM_PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
|
||||
ofs.WriteStrings("AM_HEADERS", headers);
|
||||
ofs.WriteStrings("AM_HEADERS_FLAGS", headersFlags);
|
||||
ofs.WriteStrings("AM_HEADERS_BUILD_PATHS", headersBuildPaths);
|
||||
ofs.WriteStrings("AM_SOURCES", sources);
|
||||
ofs.WriteStrings("AM_SOURCES_FLAGS", sourcesFlags);
|
||||
|
||||
// Write moc settings
|
||||
if (this->Moc.Enabled) {
|
||||
ofs.Write("# MOC settings\n");
|
||||
ofs.WriteStrings("AM_MOC_SKIP", moc_skip);
|
||||
ofs.WriteStrings("AM_MOC_DEFINITIONS", this->Moc.Defines);
|
||||
ofs.WriteConfigStrings("AM_MOC_DEFINITIONS", this->Moc.ConfigDefines);
|
||||
ofs.WriteStrings("AM_MOC_INCLUDES", this->Moc.Includes);
|
||||
ofs.WriteConfigStrings("AM_MOC_INCLUDES", this->Moc.ConfigIncludes);
|
||||
ofs.Write("AM_MOC_OPTIONS",
|
||||
this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS"));
|
||||
ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE"));
|
||||
ofs.Write("AM_MOC_PATH_PREFIX",
|
||||
this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"));
|
||||
ofs.Write("AM_MOC_MACRO_NAMES",
|
||||
this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"));
|
||||
ofs.Write("AM_MOC_DEPEND_FILTERS",
|
||||
this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
|
||||
ofs.Write("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
|
||||
}
|
||||
|
||||
// Write uic settings
|
||||
if (this->Uic.Enabled) {
|
||||
// Add skipped .ui files
|
||||
uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end());
|
||||
|
||||
ofs.Write("# UIC settings\n");
|
||||
ofs.WriteStrings("AM_UIC_SKIP", uic_skip);
|
||||
ofs.WriteStrings("AM_UIC_TARGET_OPTIONS", this->Uic.Options);
|
||||
ofs.WriteConfigStrings("AM_UIC_TARGET_OPTIONS", this->Uic.ConfigOptions);
|
||||
ofs.WriteStrings("AM_UIC_OPTIONS_FILES", this->Uic.FileFiles);
|
||||
ofs.WriteNestedLists("AM_UIC_OPTIONS_OPTIONS", this->Uic.FileOptions);
|
||||
ofs.WriteStrings("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths);
|
||||
}
|
||||
} else {
|
||||
cmSystemTools::Error(cmStrCat("AutoGen: Could not write file ",
|
||||
this->AutogenTarget.InfoFile));
|
||||
return false;
|
||||
std::sort(headers.begin(), headers.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->FullPath < b->FullPath);
|
||||
});
|
||||
}
|
||||
|
||||
// Filter sources
|
||||
{
|
||||
sources.reserve(this->AutogenTarget.Sources.size());
|
||||
for (auto const& pair : this->AutogenTarget.Sources) {
|
||||
MUFile const* const muf = pair.second.get();
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->FullPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
sources.emplace_back(muf);
|
||||
}
|
||||
}
|
||||
std::sort(sources.begin(), sources.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->FullPath < b->FullPath);
|
||||
});
|
||||
}
|
||||
|
||||
// Info writer
|
||||
InfoWriter info;
|
||||
|
||||
// General
|
||||
info.SetBool("MULTI_CONFIG", this->MultiConfig);
|
||||
info.SetUInt("PARALLEL", this->AutogenTarget.Parallel);
|
||||
info.SetUInt("VERBOSITY", this->Verbosity);
|
||||
|
||||
// Directories
|
||||
info.Set("CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
|
||||
info.Set("CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
|
||||
info.Set("CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR"));
|
||||
info.Set("CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR"));
|
||||
info.Set("BUILD_DIR", this->Dir.Build);
|
||||
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
|
||||
|
||||
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
|
||||
info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
|
||||
info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
|
||||
|
||||
info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
|
||||
info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile);
|
||||
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
|
||||
info.SetArray("HEADER_EXTENSIONS",
|
||||
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
|
||||
info.SetArrayArray(
|
||||
"HEADERS", headers, [this](Json::Value& jval, MUFile const* muf) {
|
||||
jval.resize(3u);
|
||||
jval[0u] = muf->FullPath;
|
||||
jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
|
||||
jval[2u] = this->GetMocBuildPath(*muf);
|
||||
});
|
||||
info.SetArrayArray(
|
||||
"SOURCES", sources, [](Json::Value& jval, MUFile const* muf) {
|
||||
jval.resize(2u);
|
||||
jval[0u] = muf->FullPath;
|
||||
jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
|
||||
});
|
||||
|
||||
// Write moc settings
|
||||
if (this->Moc.Enabled) {
|
||||
info.SetArray("MOC_SKIP", moc_skip);
|
||||
info.SetConfigArray("MOC_DEFINITIONS", this->Moc.Defines);
|
||||
info.SetConfigArray("MOC_INCLUDES", this->Moc.Includes);
|
||||
info.SetArray("MOC_OPTIONS", this->Moc.Options);
|
||||
info.SetBool("MOC_RELAXED_MODE", this->Moc.RelaxedMode);
|
||||
info.SetBool("MOC_PATH_PREFIX", this->Moc.PathPrefix);
|
||||
info.SetArray("MOC_MACRO_NAMES", this->Moc.MacroNames);
|
||||
info.SetArrayArray(
|
||||
"MOC_DEPEND_FILTERS", this->Moc.DependFilters,
|
||||
[](Json::Value& jval, std::pair<std::string, std::string> const& pair) {
|
||||
jval.resize(2u);
|
||||
jval[0u] = pair.first;
|
||||
jval[1u] = pair.second;
|
||||
});
|
||||
info.Set("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
|
||||
info.SetArray("MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
|
||||
info.SetConfig("MOC_PREDEFS_FILE", this->Moc.PredefsFile);
|
||||
}
|
||||
|
||||
// Write uic settings
|
||||
if (this->Uic.Enabled) {
|
||||
// Add skipped .ui files
|
||||
uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end());
|
||||
|
||||
info.SetArray("UIC_SKIP", uic_skip);
|
||||
info.SetArrayArray("UIC_UI_FILES", this->Uic.UiFiles,
|
||||
[](Json::Value& jval, UicT::UiFileT const& uiFile) {
|
||||
jval.resize(2u);
|
||||
jval[0u] = uiFile.first;
|
||||
InfoWriter::MakeStringArray(jval[1u], uiFile.second);
|
||||
});
|
||||
info.SetConfigArray("UIC_OPTIONS", this->Uic.Options);
|
||||
info.SetArray("UIC_SEARCH_PATHS", this->Uic.SearchPaths);
|
||||
}
|
||||
|
||||
info.Save(this->AutogenTarget.InfoFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenInitializer::SetupWriteRccInfo()
|
||||
{
|
||||
for (Qrc const& qrc : this->Rcc.Qrcs) {
|
||||
InfoWriter ofs(qrc.InfoFile);
|
||||
if (ofs) {
|
||||
// Utility lambdas
|
||||
auto MfDef = [this](const char* key) {
|
||||
return this->Makefile->GetSafeDefinition(key);
|
||||
};
|
||||
// Utility lambdas
|
||||
auto MfDef = [this](std::string const& key) {
|
||||
return this->Makefile->GetSafeDefinition(key);
|
||||
};
|
||||
|
||||
// Write
|
||||
ofs.Write("# Configurations\n");
|
||||
ofs.Write("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE");
|
||||
ofs.Write("ARCC_VERBOSITY", this->Verbosity);
|
||||
ofs.Write("# Settings file\n");
|
||||
ofs.Write("ARCC_SETTINGS_FILE", qrc.SettingsFile);
|
||||
ofs.WriteConfig("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile);
|
||||
InfoWriter info;
|
||||
|
||||
ofs.Write("# Directories\n");
|
||||
ofs.Write("ARCC_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
|
||||
ofs.Write("ARCC_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
|
||||
ofs.Write("ARCC_BUILD_DIR", this->Dir.Build);
|
||||
ofs.Write("ARCC_INCLUDE_DIR", this->Dir.Include);
|
||||
ofs.WriteConfig("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude);
|
||||
// General
|
||||
info.SetBool("MULTI_CONFIG", this->MultiConfig);
|
||||
info.SetUInt("VERBOSITY", this->Verbosity);
|
||||
|
||||
ofs.Write("# Rcc executable\n");
|
||||
ofs.Write("ARCC_RCC_EXECUTABLE", this->Rcc.Executable);
|
||||
ofs.WriteStrings("ARCC_RCC_LIST_OPTIONS",
|
||||
this->Rcc.ExecutableFeatures->ListOptions);
|
||||
// Files
|
||||
info.Set("LOCK_FILE", qrc.LockFile);
|
||||
info.SetConfig("SETTINGS_FILE", qrc.SettingsFile);
|
||||
|
||||
ofs.Write("# Rcc job\n");
|
||||
ofs.Write("ARCC_LOCK_FILE", qrc.LockFile);
|
||||
ofs.Write("ARCC_SOURCE", qrc.QrcFile);
|
||||
ofs.Write("ARCC_OUTPUT_CHECKSUM", qrc.QrcPathChecksum);
|
||||
ofs.Write("ARCC_OUTPUT_NAME",
|
||||
cmSystemTools::GetFilenameName(qrc.OutputFile));
|
||||
ofs.WriteStrings("ARCC_OPTIONS", qrc.Options);
|
||||
ofs.WriteStrings("ARCC_INPUTS", qrc.Resources);
|
||||
} else {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("AutoRcc: Could not write file ", qrc.InfoFile));
|
||||
return false;
|
||||
}
|
||||
// Directories
|
||||
info.Set("CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
|
||||
info.Set("CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
|
||||
info.Set("CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR"));
|
||||
info.Set("CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR"));
|
||||
info.Set("BUILD_DIR", this->Dir.Build);
|
||||
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
|
||||
|
||||
// rcc executable
|
||||
info.Set("RCC_EXECUTABLE", this->Rcc.Executable);
|
||||
info.SetArray("RCC_LIST_OPTIONS",
|
||||
this->Rcc.ExecutableFeatures->ListOptions);
|
||||
|
||||
// qrc file
|
||||
info.Set("SOURCE", qrc.QrcFile);
|
||||
info.Set("OUTPUT_CHECKSUM", qrc.QrcPathChecksum);
|
||||
info.Set("OUTPUT_NAME", cmSystemTools::GetFilenameName(qrc.OutputFile));
|
||||
info.SetArray("OPTIONS", qrc.Options);
|
||||
info.SetArray("INPUTS", qrc.Resources);
|
||||
|
||||
info.Save(qrc.InfoFile);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1509,6 +1525,28 @@ void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
|
||||
fileName.c_str(), false);
|
||||
}
|
||||
|
||||
void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString,
|
||||
cm::string_view prefix,
|
||||
cm::string_view suffix)
|
||||
{
|
||||
configString.Default = cmStrCat(prefix, suffix);
|
||||
if (this->MultiConfig) {
|
||||
for (auto const& cfg : this->ConfigsList) {
|
||||
configString.Config[cfg] = cmStrCat(prefix, '_', cfg, suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmQtAutoGenInitializer::ConfigFileClean(ConfigString& configString)
|
||||
{
|
||||
this->AddCleanFile(configString.Default);
|
||||
if (this->MultiConfig) {
|
||||
for (auto const& pair : configString.Config) {
|
||||
this->AddCleanFile(pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<cmQtAutoGen::IntegerVersion, unsigned int>
|
||||
cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
|
||||
{
|
||||
@@ -1581,6 +1619,30 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenInitializer::GetMocBuildPath(MUFile const& muf)
|
||||
{
|
||||
std::string res;
|
||||
if (!muf.MocIt) {
|
||||
return res;
|
||||
}
|
||||
{
|
||||
std::string const basePath =
|
||||
cmStrCat(this->PathCheckSum.getPart(muf.FullPath), "/moc_",
|
||||
FileNameWithoutLastExtension(muf.FullPath));
|
||||
std::string suffix;
|
||||
constexpr std::size_t num_tries_max = 256;
|
||||
for (std::size_t ii = 0; ii != num_tries_max; ++ii) {
|
||||
res = cmStrCat(basePath, suffix, ".cpp");
|
||||
if (this->Moc.EmittedBuildPaths.emplace(res).second) {
|
||||
break;
|
||||
}
|
||||
// Compute new suffix
|
||||
suffix = cmStrCat('_', ii + 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
|
||||
const std::string& executable,
|
||||
bool ignoreMissingTarget) const
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
#define cmQtAutoGenInitializer_h
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmFilePathChecksum.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -32,6 +31,23 @@ class cmTarget;
|
||||
class cmQtAutoGenInitializer : public cmQtAutoGen
|
||||
{
|
||||
public:
|
||||
/** String value with per configuration variants. */
|
||||
class ConfigString
|
||||
{
|
||||
public:
|
||||
std::string Default;
|
||||
std::unordered_map<std::string, std::string> Config;
|
||||
};
|
||||
|
||||
/** String values with per configuration variants. */
|
||||
template <typename C>
|
||||
class ConfigStrings
|
||||
{
|
||||
public:
|
||||
C Default;
|
||||
std::unordered_map<std::string, C> Config;
|
||||
};
|
||||
|
||||
/** rcc job. */
|
||||
class Qrc
|
||||
{
|
||||
@@ -41,8 +57,7 @@ public:
|
||||
std::string QrcName;
|
||||
std::string QrcPathChecksum;
|
||||
std::string InfoFile;
|
||||
std::string SettingsFile;
|
||||
std::map<std::string, std::string> ConfigSettingsFile;
|
||||
ConfigString SettingsFile;
|
||||
std::string OutputFile;
|
||||
bool Generated = false;
|
||||
bool Unique = false;
|
||||
@@ -63,7 +78,7 @@ public:
|
||||
};
|
||||
using MUFileHandle = std::unique_ptr<MUFile>;
|
||||
|
||||
/** Abstract moc/uic/rcc generator variables base class */
|
||||
/** Abstract moc/uic/rcc generator variables base class. */
|
||||
struct GenVarsT
|
||||
{
|
||||
bool Enabled = false;
|
||||
@@ -81,39 +96,6 @@ public:
|
||||
, GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){};
|
||||
};
|
||||
|
||||
/** Writes a CMake info file. */
|
||||
class InfoWriter
|
||||
{
|
||||
public:
|
||||
/** Open the given file. */
|
||||
InfoWriter(std::string const& filename);
|
||||
|
||||
/** @return True if the file is open. */
|
||||
explicit operator bool() const { return static_cast<bool>(Ofs_); }
|
||||
|
||||
void Write(cm::string_view text) { Ofs_ << text; }
|
||||
void Write(cm::string_view, std::string const& value);
|
||||
void WriteUInt(cm::string_view, unsigned int value);
|
||||
|
||||
template <class C>
|
||||
void WriteStrings(cm::string_view, C const& container);
|
||||
void WriteConfig(cm::string_view,
|
||||
std::map<std::string, std::string> const& map);
|
||||
template <class C>
|
||||
void WriteConfigStrings(cm::string_view,
|
||||
std::map<std::string, C> const& map);
|
||||
void WriteNestedLists(cm::string_view,
|
||||
std::vector<std::vector<std::string>> const& lists);
|
||||
|
||||
private:
|
||||
template <class IT>
|
||||
static std::string ListJoin(IT it_begin, IT it_end);
|
||||
static std::string ConfigKey(cm::string_view, std::string const& config);
|
||||
|
||||
private:
|
||||
cmGeneratedFileStream Ofs_;
|
||||
};
|
||||
|
||||
public:
|
||||
/** @return The detected Qt version and the required Qt major version. */
|
||||
static std::pair<IntegerVersion, unsigned int> GetQtVersion(
|
||||
@@ -153,6 +135,12 @@ private:
|
||||
cm::string_view genNameUpper);
|
||||
void AddCleanFile(std::string const& fileName);
|
||||
|
||||
void ConfigFileNames(ConfigString& configString, cm::string_view prefix,
|
||||
cm::string_view suffix);
|
||||
void ConfigFileClean(ConfigString& configString);
|
||||
|
||||
std::string GetMocBuildPath(MUFile const& muf);
|
||||
|
||||
bool GetQtExecutable(GenVarsT& genVars, const std::string& executable,
|
||||
bool ignoreMissingTarget) const;
|
||||
|
||||
@@ -162,16 +150,17 @@ private:
|
||||
cmGlobalGenerator* GlobalGen = nullptr;
|
||||
cmLocalGenerator* LocalGen = nullptr;
|
||||
cmMakefile* Makefile = nullptr;
|
||||
cmFilePathChecksum const PathCheckSum;
|
||||
|
||||
// -- Configuration
|
||||
IntegerVersion QtVersion;
|
||||
unsigned int Verbosity = 0;
|
||||
bool MultiConfig = false;
|
||||
std::string ConfigDefault;
|
||||
std::vector<std::string> ConfigsList;
|
||||
std::string Verbosity;
|
||||
std::string TargetsFolder;
|
||||
bool CMP0071Accept = false;
|
||||
bool CMP0071Warn = false;
|
||||
std::string ConfigDefault;
|
||||
std::vector<std::string> ConfigsList;
|
||||
std::string TargetsFolder;
|
||||
|
||||
/** Common directories. */
|
||||
struct
|
||||
@@ -179,8 +168,7 @@ private:
|
||||
std::string Info;
|
||||
std::string Build;
|
||||
std::string Work;
|
||||
std::string Include;
|
||||
std::map<std::string, std::string> ConfigInclude;
|
||||
ConfigString Include;
|
||||
std::string IncludeGenExp;
|
||||
} Dir;
|
||||
|
||||
@@ -190,12 +178,11 @@ private:
|
||||
std::string Name;
|
||||
bool GlobalTarget = false;
|
||||
// Settings
|
||||
std::string Parallel;
|
||||
unsigned int Parallel = 1;
|
||||
// Configuration files
|
||||
std::string InfoFile;
|
||||
std::string SettingsFile;
|
||||
std::string ParseCacheFile;
|
||||
std::map<std::string, std::string> ConfigSettingsFile;
|
||||
ConfigString SettingsFile;
|
||||
ConfigString ParseCacheFile;
|
||||
// Dependencies
|
||||
bool DependOrigin = false;
|
||||
std::set<std::string> DependFiles;
|
||||
@@ -212,26 +199,37 @@ private:
|
||||
MocT()
|
||||
: GenVarsT(GenT::MOC){};
|
||||
|
||||
std::string PredefsCmd;
|
||||
std::vector<std::string> Includes;
|
||||
std::map<std::string, std::vector<std::string>> ConfigIncludes;
|
||||
std::set<std::string> Defines;
|
||||
std::map<std::string, std::set<std::string>> ConfigDefines;
|
||||
std::string MocsCompilation;
|
||||
bool RelaxedMode = false;
|
||||
bool PathPrefix = false;
|
||||
std::string CompilationFile;
|
||||
// Compiler implicit pre defines
|
||||
std::vector<std::string> PredefsCmd;
|
||||
ConfigString PredefsFile;
|
||||
// Defines
|
||||
ConfigStrings<std::set<std::string>> Defines;
|
||||
// Includes
|
||||
ConfigStrings<std::vector<std::string>> Includes;
|
||||
// Options
|
||||
std::vector<std::string> Options;
|
||||
// Filters
|
||||
std::vector<std::string> MacroNames;
|
||||
std::vector<std::pair<std::string, std::string>> DependFilters;
|
||||
// Utility
|
||||
std::unordered_set<std::string> EmittedBuildPaths;
|
||||
} Moc;
|
||||
|
||||
/** uic variables. */
|
||||
struct UicT : public GenVarsT
|
||||
{
|
||||
using UiFileT = std::pair<std::string, std::vector<std::string>>;
|
||||
|
||||
UicT()
|
||||
: GenVarsT(GenT::UIC){};
|
||||
|
||||
std::set<std::string> SkipUi;
|
||||
std::vector<UiFileT> UiFiles;
|
||||
ConfigStrings<std::vector<std::string>> Options;
|
||||
std::vector<std::string> SearchPaths;
|
||||
std::vector<std::string> Options;
|
||||
std::map<std::string, std::vector<std::string>> ConfigOptions;
|
||||
std::vector<std::string> FileFiles;
|
||||
std::vector<std::vector<std::string>> FileOptions;
|
||||
} Uic;
|
||||
|
||||
/** rcc variables. */
|
||||
|
||||
+222
-38
@@ -2,19 +2,11 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmQtAutoGenerator.h"
|
||||
|
||||
#include <cm/memory>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmState.h"
|
||||
#include "cmStateDirectory.h"
|
||||
#include "cmStateSnapshot.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmake.h"
|
||||
#include "cm_jsoncpp_reader.h"
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
cmQtAutoGenerator::Logger::Logger()
|
||||
{
|
||||
@@ -44,13 +36,10 @@ cmQtAutoGenerator::Logger::Logger()
|
||||
|
||||
cmQtAutoGenerator::Logger::~Logger() = default;
|
||||
|
||||
void cmQtAutoGenerator::Logger::RaiseVerbosity(std::string const& value)
|
||||
void cmQtAutoGenerator::Logger::RaiseVerbosity(unsigned int value)
|
||||
{
|
||||
unsigned long verbosity = 0;
|
||||
if (cmStrToULong(value, &verbosity)) {
|
||||
if (this->Verbosity_ < verbosity) {
|
||||
this->Verbosity_ = static_cast<unsigned int>(verbosity);
|
||||
}
|
||||
if (this->Verbosity_ < value) {
|
||||
this->Verbosity_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +203,10 @@ bool cmQtAutoGenerator::FileDiffers(std::string const& filename,
|
||||
return differs;
|
||||
}
|
||||
|
||||
cmQtAutoGenerator::cmQtAutoGenerator() = default;
|
||||
cmQtAutoGenerator::cmQtAutoGenerator(GenT genType)
|
||||
: GenType_(genType)
|
||||
{
|
||||
}
|
||||
|
||||
cmQtAutoGenerator::~cmQtAutoGenerator() = default;
|
||||
|
||||
@@ -223,7 +215,7 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile,
|
||||
{
|
||||
// Info settings
|
||||
InfoFile_ = infoFile;
|
||||
cmSystemTools::ConvertToUnixSlashes(InfoFile_);
|
||||
cmSystemTools::CollapseFullPath(InfoFile_);
|
||||
if (!InfoFileTime_.Load(InfoFile_)) {
|
||||
cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ",
|
||||
Quoted(InfoFile_), " is not readable\n"));
|
||||
@@ -232,29 +224,221 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile,
|
||||
InfoDir_ = cmSystemTools::GetFilenamePath(infoFile);
|
||||
InfoConfig_ = config;
|
||||
|
||||
bool success = false;
|
||||
// Read info file
|
||||
{
|
||||
cmake cm(cmake::RoleScript, cmState::Unknown);
|
||||
cm.SetHomeOutputDirectory(InfoDir());
|
||||
cm.SetHomeDirectory(InfoDir());
|
||||
cm.GetCurrentSnapshot().SetDefaultDefinitions();
|
||||
cmGlobalGenerator gg(&cm);
|
||||
|
||||
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
|
||||
snapshot.GetDirectory().SetCurrentBinary(InfoDir());
|
||||
snapshot.GetDirectory().SetCurrentSource(InfoDir());
|
||||
|
||||
auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
|
||||
// The OLD/WARN behavior for policy CMP0053 caused a speed regression.
|
||||
// https://gitlab.kitware.com/cmake/cmake/issues/17570
|
||||
makefile->SetPolicyVersion("3.9", std::string());
|
||||
gg.SetCurrentMakefile(makefile.get());
|
||||
success = this->Init(makefile.get());
|
||||
cmsys::ifstream ifs(InfoFile_.c_str(), (std::ios::in | std::ios::binary));
|
||||
if (!ifs) {
|
||||
Log().Error(GenType_,
|
||||
cmStrCat("Could not to open info file ", Quoted(InfoFile_)));
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ifs >> Info_;
|
||||
} catch (...) {
|
||||
Log().Error(GenType_,
|
||||
cmStrCat("Could not read info file ", Quoted(InfoFile_)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
success = this->Process();
|
||||
// Info: setup logger
|
||||
{
|
||||
unsigned int value = 0;
|
||||
if (!InfoUInt("VERBOSITY", value, false)) {
|
||||
return false;
|
||||
}
|
||||
Logger_.RaiseVerbosity(value);
|
||||
}
|
||||
return success;
|
||||
// Info: setup project directories
|
||||
if (!InfoString("CMAKE_SOURCE_DIR", ProjectDirs_.Source, true) ||
|
||||
!InfoString("CMAKE_BINARY_DIR", ProjectDirs_.Binary, true) ||
|
||||
!InfoString("CMAKE_CURRENT_SOURCE_DIR", ProjectDirs_.CurrentSource,
|
||||
true) ||
|
||||
!InfoString("CMAKE_CURRENT_BINARY_DIR", ProjectDirs_.CurrentBinary,
|
||||
true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->InitFromInfo()) {
|
||||
return false;
|
||||
}
|
||||
// Clear info
|
||||
Info_ = Json::nullValue;
|
||||
|
||||
return this->Process();
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::LogInfoError(GenT genType,
|
||||
cm::string_view message) const
|
||||
{
|
||||
this->Log().Error(
|
||||
genType,
|
||||
cmStrCat("Info error in info file\n", Quoted(InfoFile()), ":\n", message));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::LogInfoError(cm::string_view message) const
|
||||
{
|
||||
return LogInfoError(GenType_, message);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::JsonGetArray(std::vector<std::string>& list,
|
||||
Json::Value const& jval)
|
||||
{
|
||||
Json::ArrayIndex const arraySize = jval.size();
|
||||
if (arraySize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool picked = false;
|
||||
list.reserve(list.size() + arraySize);
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
Json::Value const& ival = jval[ii];
|
||||
if (ival.isString()) {
|
||||
list.emplace_back(ival.asString());
|
||||
picked = true;
|
||||
}
|
||||
}
|
||||
return picked;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::JsonGetArray(std::unordered_set<std::string>& list,
|
||||
Json::Value const& jval)
|
||||
{
|
||||
Json::ArrayIndex const arraySize = jval.size();
|
||||
if (arraySize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool picked = false;
|
||||
list.reserve(list.size() + arraySize);
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
Json::Value const& ival = jval[ii];
|
||||
if (ival.isString()) {
|
||||
list.emplace(ival.asString());
|
||||
picked = true;
|
||||
}
|
||||
}
|
||||
return picked;
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::InfoConfigKey(std::string const& key) const
|
||||
{
|
||||
return cmStrCat(key, '_', InfoConfig());
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoString(std::string const& key, std::string& value,
|
||||
bool required) const
|
||||
{
|
||||
Json::Value const& jval = Info()[key];
|
||||
if (!jval.isString()) {
|
||||
if (!jval.isNull() || required) {
|
||||
return LogInfoError(cmStrCat(key, " is not a string."));
|
||||
}
|
||||
} else {
|
||||
value = jval.asString();
|
||||
if (value.empty() && required) {
|
||||
return LogInfoError(cmStrCat(key, " is empty."));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoStringConfig(std::string const& key,
|
||||
std::string& value,
|
||||
|
||||
bool required) const
|
||||
{
|
||||
{ // Try config
|
||||
std::string const configKey = InfoConfigKey(key);
|
||||
Json::Value const& jval = Info_[configKey];
|
||||
if (!jval.isNull()) {
|
||||
if (!jval.isString()) {
|
||||
return LogInfoError(cmStrCat(configKey, " is not a string."));
|
||||
}
|
||||
value = jval.asString();
|
||||
if (required && value.empty()) {
|
||||
return LogInfoError(cmStrCat(configKey, " is empty."));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Try plain
|
||||
return InfoString(key, value, required);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoBool(std::string const& key, bool& value,
|
||||
bool required) const
|
||||
{
|
||||
Json::Value const& jval = Info()[key];
|
||||
if (jval.isBool()) {
|
||||
value = jval.asBool();
|
||||
} else {
|
||||
if (!jval.isNull() || required) {
|
||||
return LogInfoError(cmStrCat(key, " is not a boolean."));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoUInt(std::string const& key, unsigned int& value,
|
||||
bool required) const
|
||||
{
|
||||
Json::Value const& jval = Info()[key];
|
||||
if (jval.isUInt()) {
|
||||
value = jval.asUInt();
|
||||
} else {
|
||||
if (!jval.isNull() || required) {
|
||||
return LogInfoError(cmStrCat(key, " is not an unsigned integer."));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoArray(std::string const& key,
|
||||
std::vector<std::string>& list,
|
||||
bool required) const
|
||||
{
|
||||
Json::Value const& jval = Info()[key];
|
||||
if (!jval.isArray()) {
|
||||
if (!jval.isNull() || required) {
|
||||
return LogInfoError(cmStrCat(key, " is not an array."));
|
||||
}
|
||||
}
|
||||
return JsonGetArray(list, jval) || !required;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoArray(std::string const& key,
|
||||
std::unordered_set<std::string>& list,
|
||||
bool required) const
|
||||
{
|
||||
Json::Value const& jval = Info()[key];
|
||||
if (!jval.isArray()) {
|
||||
if (!jval.isNull() || required) {
|
||||
return LogInfoError(cmStrCat(key, " is not an array."));
|
||||
}
|
||||
}
|
||||
return JsonGetArray(list, jval) || !required;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::InfoArrayConfig(std::string const& key,
|
||||
std::vector<std::string>& list,
|
||||
bool required) const
|
||||
{
|
||||
{ // Try config
|
||||
std::string const configKey = InfoConfigKey(key);
|
||||
Json::Value const& jval = Info()[configKey];
|
||||
if (!jval.isNull()) {
|
||||
if (!jval.isArray()) {
|
||||
return LogInfoError(cmStrCat(configKey, " is not an array string."));
|
||||
}
|
||||
if (!JsonGetArray(list, jval) && required) {
|
||||
return LogInfoError(cmStrCat(configKey, " is empty."));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Try plain
|
||||
return InfoArray(key, list, required);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::SettingsFind(std::string const& content,
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
|
||||
#include "cmFileTime.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cm_jsoncpp_value.h"
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
/** \class cmQtAutoGenerator
|
||||
* \brief Base class for QtAutoGen generators
|
||||
*/
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
// -- Verbosity
|
||||
unsigned int Verbosity() const { return this->Verbosity_; }
|
||||
void SetVerbosity(unsigned int value) { this->Verbosity_ = value; }
|
||||
void RaiseVerbosity(std::string const& value);
|
||||
void RaiseVerbosity(unsigned int value);
|
||||
bool Verbose() const { return (this->Verbosity_ != 0); }
|
||||
void SetVerbose(bool value) { this->Verbosity_ = value ? 1 : 0; }
|
||||
// -- Color output
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
public:
|
||||
// -- Constructors
|
||||
cmQtAutoGenerator();
|
||||
cmQtAutoGenerator(GenT genType);
|
||||
virtual ~cmQtAutoGenerator();
|
||||
|
||||
cmQtAutoGenerator(cmQtAutoGenerator const&) = delete;
|
||||
@@ -91,10 +91,39 @@ public:
|
||||
|
||||
// -- InfoFile
|
||||
std::string const& InfoFile() const { return InfoFile_; }
|
||||
Json::Value const& Info() const { return Info_; }
|
||||
cmFileTime const& InfoFileTime() const { return InfoFileTime_; }
|
||||
std::string const& InfoDir() const { return InfoDir_; }
|
||||
std::string const& InfoConfig() const { return InfoConfig_; }
|
||||
|
||||
bool LogInfoError(GenT genType, cm::string_view message) const;
|
||||
bool LogInfoError(cm::string_view message) const;
|
||||
|
||||
/** Returns true if strings were appended to the list. */
|
||||
static bool JsonGetArray(std::vector<std::string>& list,
|
||||
Json::Value const& jval);
|
||||
/** Returns true if strings were found in the JSON array. */
|
||||
static bool JsonGetArray(std::unordered_set<std::string>& list,
|
||||
Json::Value const& jval);
|
||||
|
||||
std::string InfoConfigKey(std::string const& key) const;
|
||||
|
||||
/** Returns false if the JSON value isn't a string. */
|
||||
bool InfoString(std::string const& key, std::string& value,
|
||||
bool required) const;
|
||||
bool InfoStringConfig(std::string const& key, std::string& value,
|
||||
bool required) const;
|
||||
bool InfoBool(std::string const& key, bool& value, bool required) const;
|
||||
bool InfoUInt(std::string const& key, unsigned int& value,
|
||||
bool required) const;
|
||||
/** Returns false if the JSON value isn't an array. */
|
||||
bool InfoArray(std::string const& key, std::vector<std::string>& list,
|
||||
bool required) const;
|
||||
bool InfoArray(std::string const& key, std::unordered_set<std::string>& list,
|
||||
bool required) const;
|
||||
bool InfoArrayConfig(std::string const& key, std::vector<std::string>& list,
|
||||
bool required) const;
|
||||
|
||||
// -- Directories
|
||||
ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; }
|
||||
|
||||
@@ -104,16 +133,22 @@ public:
|
||||
|
||||
protected:
|
||||
// -- Abstract processing interface
|
||||
virtual bool Init(cmMakefile* makefile) = 0;
|
||||
virtual bool InitFromInfo() = 0;
|
||||
virtual bool Process() = 0;
|
||||
ProjectDirsT& ProjectDirsRef() { return ProjectDirs_; }
|
||||
// - Utility classes
|
||||
Logger const& Log() const { return Logger_; }
|
||||
|
||||
private:
|
||||
// -- Info settings
|
||||
// -- Generator type
|
||||
GenT GenType_;
|
||||
// -- Logging
|
||||
Logger Logger_;
|
||||
// -- Info file
|
||||
std::string InfoFile_;
|
||||
cmFileTime InfoFileTime_;
|
||||
std::string InfoDir_;
|
||||
std::string InfoConfig_;
|
||||
Json::Value Info_;
|
||||
// -- Directories
|
||||
ProjectDirsT ProjectDirs_;
|
||||
};
|
||||
|
||||
+256
-281
@@ -11,19 +11,22 @@
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmake.h"
|
||||
#include "cm_jsoncpp_value.h"
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
static constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
|
||||
static constexpr std::size_t UiUnderscoreLength = 3; // Length of "ui_"
|
||||
namespace {
|
||||
|
||||
constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
|
||||
constexpr std::size_t UiUnderscoreLength = 3; // Length of "ui_"
|
||||
|
||||
} // End of unnamed namespace
|
||||
|
||||
cmQtAutoMocUic::IncludeKeyT::IncludeKeyT(std::string const& key,
|
||||
std::size_t basePrefixLength)
|
||||
@@ -1464,10 +1467,10 @@ void cmQtAutoMocUic::JobCompileUicT::Process()
|
||||
std::vector<std::string> cmd;
|
||||
cmd.push_back(UicConst().Executable);
|
||||
{
|
||||
std::vector<std::string> allOpts = UicConst().TargetOptions;
|
||||
auto optionIt = UicConst().Options.find(sourceFile);
|
||||
if (optionIt != UicConst().Options.end()) {
|
||||
UicMergeOptions(allOpts, optionIt->second,
|
||||
std::vector<std::string> allOpts = UicConst().Options;
|
||||
auto optionIt = UicConst().UiFiles.find(sourceFile);
|
||||
if (optionIt != UicConst().UiFiles.end()) {
|
||||
UicMergeOptions(allOpts, optionIt->second.Options,
|
||||
(BaseConst().QtVersionMajor == 5));
|
||||
}
|
||||
cmAppend(cmd, allOpts);
|
||||
@@ -1548,338 +1551,310 @@ void cmQtAutoMocUic::JobFinishT::Process()
|
||||
Gen()->AbortSuccess();
|
||||
}
|
||||
|
||||
cmQtAutoMocUic::cmQtAutoMocUic() = default;
|
||||
cmQtAutoMocUic::cmQtAutoMocUic()
|
||||
: cmQtAutoGenerator(GenT::GEN)
|
||||
{
|
||||
}
|
||||
cmQtAutoMocUic::~cmQtAutoMocUic() = default;
|
||||
|
||||
bool cmQtAutoMocUic::Init(cmMakefile* makefile)
|
||||
bool cmQtAutoMocUic::InitFromInfo()
|
||||
{
|
||||
// Utility lambdas
|
||||
auto InfoGet = [makefile](cm::string_view key) {
|
||||
return makefile->GetSafeDefinition(std::string(key));
|
||||
};
|
||||
auto InfoGetBool = [makefile](cm::string_view key) {
|
||||
return makefile->IsOn(std::string(key));
|
||||
};
|
||||
auto InfoGetList =
|
||||
[makefile](cm::string_view key) -> std::vector<std::string> {
|
||||
return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
|
||||
};
|
||||
auto InfoGetLists =
|
||||
[makefile](cm::string_view key) -> std::vector<std::vector<std::string>> {
|
||||
std::vector<std::vector<std::string>> lists;
|
||||
{
|
||||
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);
|
||||
std::string::size_type length =
|
||||
(next != std::string::npos) ? next - pos : value.size() - pos;
|
||||
// Remove enclosing braces
|
||||
if (length >= 2) {
|
||||
std::string::const_iterator itBeg = value.begin() + (pos + 1);
|
||||
std::string::const_iterator itEnd = itBeg + (length - 2);
|
||||
lists.emplace_back(cmExpandedList(std::string(itBeg, itEnd)));
|
||||
}
|
||||
pos += length;
|
||||
pos += ListSep.size();
|
||||
}
|
||||
}
|
||||
return lists;
|
||||
};
|
||||
auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
|
||||
if (const char* valueConf =
|
||||
makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
|
||||
return std::string(valueConf);
|
||||
}
|
||||
return makefile->GetSafeDefinition(std::string(key));
|
||||
};
|
||||
auto InfoGetConfigList =
|
||||
[&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
|
||||
return cmExpandedList(InfoGetConfig(key));
|
||||
};
|
||||
auto LogInfoError = [this](cm::string_view msg) -> bool {
|
||||
this->Log().Error(GenT::GEN,
|
||||
cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
|
||||
// -- Required settings
|
||||
if (!InfoBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
|
||||
!InfoUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
|
||||
!InfoUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
|
||||
!InfoString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
|
||||
!InfoStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir, true) ||
|
||||
!InfoString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
|
||||
!InfoStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile, true) ||
|
||||
!InfoStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
|
||||
!InfoArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
|
||||
!InfoString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
|
||||
!InfoString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) {
|
||||
return false;
|
||||
};
|
||||
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;
|
||||
}
|
||||
return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA,
|
||||
") ", keyB, '(', sizeB, ')'));
|
||||
};
|
||||
|
||||
// -- Read info file
|
||||
if (!makefile->ReadListFile(InfoFile())) {
|
||||
return LogInfoError("File processing failed");
|
||||
}
|
||||
|
||||
// -- Meta
|
||||
Logger_.RaiseVerbosity(InfoGet("AM_VERBOSITY"));
|
||||
BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
|
||||
{
|
||||
unsigned long num = 1;
|
||||
if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) {
|
||||
num = std::max<unsigned long>(num, 1);
|
||||
num = std::min<unsigned long>(num, ParallelMax);
|
||||
}
|
||||
WorkerPool_.SetThreadCount(static_cast<unsigned int>(num));
|
||||
}
|
||||
BaseConst_.HeaderExtensions =
|
||||
makefile->GetCMakeInstance()->GetHeaderExtensions();
|
||||
|
||||
// - Files and directories
|
||||
ProjectDirsRef().Source = InfoGet("AM_CMAKE_SOURCE_DIR");
|
||||
ProjectDirsRef().Binary = InfoGet("AM_CMAKE_BINARY_DIR");
|
||||
ProjectDirsRef().CurrentSource = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
|
||||
ProjectDirsRef().CurrentBinary = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
|
||||
BaseConst_.AutogenBuildDir = InfoGet("AM_BUILD_DIR");
|
||||
if (BaseConst_.AutogenBuildDir.empty()) {
|
||||
return LogInfoError("Autogen build directory missing.");
|
||||
}
|
||||
BaseConst_.AutogenIncludeDir = InfoGetConfig("AM_INCLUDE_DIR");
|
||||
if (BaseConst_.AutogenIncludeDir.empty()) {
|
||||
return LogInfoError("Autogen include directory missing.");
|
||||
}
|
||||
BaseConst_.CMakeExecutable = InfoGetConfig("AM_CMAKE_EXECUTABLE");
|
||||
if (BaseConst_.CMakeExecutable.empty()) {
|
||||
return LogInfoError("CMake executable file name missing.");
|
||||
}
|
||||
// -- Checks
|
||||
if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
|
||||
return LogInfoError(cmStrCat("The CMake executable ",
|
||||
MessagePath(BaseConst_.CMakeExecutable),
|
||||
" does not exist."));
|
||||
}
|
||||
BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
|
||||
if (BaseConst_.ParseCacheFile.empty()) {
|
||||
return LogInfoError("Parse cache file name missing.");
|
||||
}
|
||||
|
||||
// - Settings file
|
||||
SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE");
|
||||
if (SettingsFile_.empty()) {
|
||||
return LogInfoError("Settings file name missing.");
|
||||
}
|
||||
// -- Evaluate values
|
||||
BaseConst_.ThreadCount = std::min(BaseConst_.ThreadCount, ParallelMax);
|
||||
WorkerPool_.SetThreadCount(BaseConst_.ThreadCount);
|
||||
|
||||
// - Qt environment
|
||||
{
|
||||
unsigned long qtv = BaseConst_.QtVersionMajor;
|
||||
if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) {
|
||||
BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
|
||||
}
|
||||
}
|
||||
|
||||
// - Moc
|
||||
MocConst_.Executable = InfoGet("AM_QT_MOC_EXECUTABLE");
|
||||
if (!MocConst().Executable.empty()) {
|
||||
// -- Moc
|
||||
if (!MocConst_.Executable.empty()) {
|
||||
// -- Moc is enabled
|
||||
MocConst_.Enabled = true;
|
||||
// Load the executable file time
|
||||
|
||||
// -- Temporary buffers
|
||||
struct
|
||||
{
|
||||
std::vector<std::string> MacroNames;
|
||||
std::vector<std::string> DependFilters;
|
||||
} tmp;
|
||||
|
||||
// -- Required settings
|
||||
if (!InfoBool("MOC_RELAXED_MODE", MocConst_.RelaxedMode, false) ||
|
||||
!InfoBool("MOC_PATH_PREFIX", MocConst_.PathPrefix, true) ||
|
||||
!InfoArray("MOC_SKIP", MocConst_.SkipList, false) ||
|
||||
!InfoArrayConfig("MOC_DEFINITIONS", MocConst_.Definitions, false) ||
|
||||
!InfoArrayConfig("MOC_INCLUDES", MocConst_.IncludePaths, false) ||
|
||||
!InfoArray("MOC_OPTIONS", MocConst_.OptionsExtra, false) ||
|
||||
!InfoStringConfig("MOC_COMPILATION_FILE", MocConst_.CompFileAbs,
|
||||
true) ||
|
||||
!InfoArray("MOC_PREDEFS_CMD", MocConst_.PredefsCmd, false) ||
|
||||
!InfoStringConfig("MOC_PREDEFS_FILE", MocConst_.PredefsFileAbs,
|
||||
!MocConst_.PredefsCmd.empty()) ||
|
||||
!InfoArray("MOC_MACRO_NAMES", tmp.MacroNames, true) ||
|
||||
!InfoArray("MOC_DEPEND_FILTERS", tmp.DependFilters, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// -- Evaluate settings
|
||||
for (std::string const& item : tmp.MacroNames) {
|
||||
MocConst_.MacroFilters.emplace_back(
|
||||
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
|
||||
}
|
||||
// Dependency filters
|
||||
{
|
||||
Json::Value const& val = Info()["MOC_DEPEND_FILTERS"];
|
||||
if (!val.isArray()) {
|
||||
return LogInfoError("MOC_DEPEND_FILTERS JSON value is not an array.");
|
||||
}
|
||||
Json::ArrayIndex const arraySize = val.size();
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
// Test entry closure
|
||||
auto testEntry = [this, ii](bool test,
|
||||
cm::string_view message) -> bool {
|
||||
if (!test) {
|
||||
this->LogInfoError(
|
||||
cmStrCat("MOC_DEPEND_FILTERS filter ", ii, ": ", message));
|
||||
}
|
||||
return !test;
|
||||
};
|
||||
|
||||
Json::Value const& pairVal = val[ii];
|
||||
|
||||
if (testEntry(pairVal.isArray(), "JSON value is not an array.") ||
|
||||
testEntry(pairVal.size() == 2, "JSON array size invalid.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value const& keyVal = pairVal[0u];
|
||||
Json::Value const& expVal = pairVal[1u];
|
||||
if (testEntry(keyVal.isString(),
|
||||
"JSON value for keyword is not a string.") ||
|
||||
testEntry(expVal.isString(),
|
||||
"JSON value for regular expression is not a string.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string const key = keyVal.asString();
|
||||
std::string const exp = expVal.asString();
|
||||
if (testEntry(!key.empty(), "Keyword is empty.") ||
|
||||
testEntry(!exp.empty(), "Regular expression is empty.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->MocConst_.DependFilters.emplace_back(key, exp);
|
||||
if (testEntry(
|
||||
this->MocConst_.DependFilters.back().Exp.is_valid(),
|
||||
cmStrCat("Regular expression compilation failed.\nKeyword: ",
|
||||
Quoted(key), "\nExpression: ", Quoted(exp)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if moc executable exists (by reading the file time)
|
||||
if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
|
||||
return LogInfoError(cmStrCat("The moc executable ",
|
||||
MessagePath(MocConst_.Executable),
|
||||
" does not exist."));
|
||||
}
|
||||
for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
|
||||
MocConst_.SkipList.insert(std::move(sfl));
|
||||
}
|
||||
MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
|
||||
MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
|
||||
MocConst_.OptionsExtra = InfoGetList("AM_MOC_OPTIONS");
|
||||
|
||||
MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
|
||||
MocConst_.PathPrefix = InfoGetBool("AM_MOC_PATH_PREFIX");
|
||||
|
||||
for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) {
|
||||
MocConst_.MacroFilters.emplace_back(
|
||||
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
|
||||
}
|
||||
{
|
||||
auto addFilter = [this, &LogInfoError](std::string const& key,
|
||||
std::string const& exp) -> bool {
|
||||
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");
|
||||
}
|
||||
if (exp.empty()) {
|
||||
return filterErr("Regular expression is empty");
|
||||
}
|
||||
this->MocConst_.DependFilters.emplace_back(key, exp);
|
||||
if (!this->MocConst_.DependFilters.back().Exp.is_valid()) {
|
||||
return filterErr("Regular expression compiling failed");
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Insert default filter for Q_PLUGIN_METADATA
|
||||
if (BaseConst().QtVersionMajor != 4) {
|
||||
if (!addFilter("Q_PLUGIN_METADATA",
|
||||
"[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
|
||||
"[^\\)]*FILE[ \t]*\"([^\"]+)\"")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Insert user defined dependency filters
|
||||
std::vector<std::string> flts = InfoGetList("AM_MOC_DEPEND_FILTERS");
|
||||
if ((flts.size() % 2) != 0) {
|
||||
return LogInfoError(
|
||||
"AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
|
||||
}
|
||||
for (auto itC = flts.begin(), itE = flts.end(); itC != itE; itC += 2) {
|
||||
if (!addFilter(*itC, *(itC + 1))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
MocConst_.PredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
|
||||
}
|
||||
|
||||
// - Uic
|
||||
UicConst_.Executable = InfoGet("AM_QT_UIC_EXECUTABLE");
|
||||
if (!UicConst().Executable.empty()) {
|
||||
// -- Uic
|
||||
if (!UicConst_.Executable.empty()) {
|
||||
// Uic is enabled
|
||||
UicConst_.Enabled = true;
|
||||
// Load the executable file time
|
||||
|
||||
// -- Required settings
|
||||
if (!InfoArray("UIC_SKIP", UicConst_.SkipList, false) ||
|
||||
!InfoArray("UIC_SEARCH_PATHS", UicConst_.SearchPaths, false) ||
|
||||
!InfoArrayConfig("UIC_OPTIONS", UicConst_.Options, false)) {
|
||||
return false;
|
||||
}
|
||||
// .ui files
|
||||
{
|
||||
Json::Value const& val = Info()["UIC_UI_FILES"];
|
||||
if (!val.isArray()) {
|
||||
return LogInfoError("UIC_UI_FILES JSON value is not an array.");
|
||||
}
|
||||
Json::ArrayIndex const arraySize = val.size();
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
// Test entry closure
|
||||
auto testEntry = [this, ii](bool test,
|
||||
cm::string_view message) -> bool {
|
||||
if (!test) {
|
||||
this->LogInfoError(
|
||||
cmStrCat("UIC_UI_FILES entry ", ii, ": ", message));
|
||||
}
|
||||
return !test;
|
||||
};
|
||||
|
||||
Json::Value const& entry = val[ii];
|
||||
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
|
||||
testEntry(entry.size() == 2, "JSON array size invalid.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value const& entryName = entry[0u];
|
||||
Json::Value const& entryOptions = entry[1u];
|
||||
if (testEntry(entryName.isString(),
|
||||
"JSON value for name is not a string.") ||
|
||||
testEntry(entryOptions.isArray(),
|
||||
"JSON value for options is not an array.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& uiFile = UicConst_.UiFiles[entryName.asString()];
|
||||
JsonGetArray(uiFile.Options, entryOptions);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Evaluate settings
|
||||
// Check if uic executable exists (by reading the file time)
|
||||
if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
|
||||
return LogInfoError(cmStrCat("The uic executable ",
|
||||
MessagePath(UicConst_.Executable),
|
||||
" does not exist."));
|
||||
}
|
||||
for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
|
||||
UicConst_.SkipList.insert(std::move(sfl));
|
||||
}
|
||||
UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
|
||||
UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_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())) {
|
||||
return false;
|
||||
}
|
||||
auto fitEnd = sources.cend();
|
||||
auto fit = sources.begin();
|
||||
auto oit = options.begin();
|
||||
while (fit != fitEnd) {
|
||||
UicConst_.Options[*fit] = std::move(*oit);
|
||||
++fit;
|
||||
++oit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Headers
|
||||
// -- Headers
|
||||
{
|
||||
// Get file lists
|
||||
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;
|
||||
if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
|
||||
return false;
|
||||
}
|
||||
if (MocConst().Enabled) {
|
||||
cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS";
|
||||
builds = InfoGetList(keyPaths);
|
||||
if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
|
||||
return false;
|
||||
}
|
||||
Json::Value const& val = Info()["HEADERS"];
|
||||
if (!val.isArray()) {
|
||||
return LogInfoError("HEADERS JSON value is not an array.");
|
||||
}
|
||||
Json::ArrayIndex const arraySize = val.size();
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
// Test entry closure
|
||||
auto testEntry = [this, ii](bool test, cm::string_view message) -> bool {
|
||||
if (!test) {
|
||||
this->LogInfoError(cmStrCat("HEADERS entry ", ii, ": ", message));
|
||||
}
|
||||
return !test;
|
||||
};
|
||||
|
||||
// Process file lists
|
||||
for (std::size_t ii = 0; ii != files.size(); ++ii) {
|
||||
std::string& fileName(files[ii]);
|
||||
std::string const& fileFlags(flags[ii]);
|
||||
if (fileFlags.size() != 2) {
|
||||
LogInfoError(cmStrCat("Invalid flags string size ", fileFlags.size(),
|
||||
"in ", keyFlags));
|
||||
Json::Value const& entry = val[ii];
|
||||
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
|
||||
testEntry(entry.size() == 3, "JSON array size invalid.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value const& entryName = entry[0u];
|
||||
Json::Value const& entryFlags = entry[1u];
|
||||
Json::Value const& entryBuild = entry[2u];
|
||||
if (testEntry(entryName.isString(),
|
||||
"JSON value for name is not a string.") ||
|
||||
testEntry(entryFlags.isString(),
|
||||
"JSON value for flags is not a string.") ||
|
||||
testEntry(entryBuild.isString(),
|
||||
"JSON value for build path is not a string.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name = entryName.asString();
|
||||
std::string flags = entryFlags.asString();
|
||||
std::string build = entryBuild.asString();
|
||||
if (testEntry(flags.size() == 2, "Invalid flags string size")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmFileTime fileTime;
|
||||
if (!fileTime.Load(fileName)) {
|
||||
LogInfoError(cmStrCat("The header file ", this->MessagePath(fileName),
|
||||
if (!fileTime.Load(name)) {
|
||||
LogInfoError(cmStrCat("The header file ", this->MessagePath(name),
|
||||
" does not exist."));
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(fileName);
|
||||
SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(name);
|
||||
sourceHandle->FileTime = fileTime;
|
||||
sourceHandle->IsHeader = true;
|
||||
sourceHandle->Moc = (fileFlags[0] == 'M');
|
||||
sourceHandle->Uic = (fileFlags[1] == 'U');
|
||||
|
||||
sourceHandle->Moc = (flags[0] == 'M');
|
||||
sourceHandle->Uic = (flags[1] == 'U');
|
||||
if (sourceHandle->Moc && MocConst().Enabled) {
|
||||
sourceHandle->BuildPath = std::move(builds[ii]);
|
||||
if (sourceHandle->BuildPath.empty()) {
|
||||
return LogInfoError("Header file build path is empty");
|
||||
if (build.empty()) {
|
||||
return LogInfoError(
|
||||
cmStrCat("Header file ", ii, " build path is empty"));
|
||||
}
|
||||
sourceHandle->BuildPath = std::move(build);
|
||||
}
|
||||
BaseEval().Headers.emplace(std::move(fileName), std::move(sourceHandle));
|
||||
BaseEval().Headers.emplace(std::move(name), std::move(sourceHandle));
|
||||
}
|
||||
}
|
||||
|
||||
// Sources
|
||||
// -- Sources
|
||||
{
|
||||
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())) {
|
||||
return false;
|
||||
Json::Value const& val = Info()["SOURCES"];
|
||||
if (!val.isArray()) {
|
||||
return LogInfoError("SOURCES JSON value is not an array.");
|
||||
}
|
||||
Json::ArrayIndex const arraySize = val.size();
|
||||
for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
|
||||
// Test entry closure
|
||||
auto testEntry = [this, ii](bool test, cm::string_view message) -> bool {
|
||||
if (!test) {
|
||||
this->LogInfoError(cmStrCat("SOURCES entry ", ii, ": ", message));
|
||||
}
|
||||
return !test;
|
||||
};
|
||||
|
||||
// Process file lists
|
||||
for (std::size_t ii = 0; ii != files.size(); ++ii) {
|
||||
std::string& fileName(files[ii]);
|
||||
std::string const& fileFlags(flags[ii]);
|
||||
if (fileFlags.size() != 2) {
|
||||
LogInfoError(cmStrCat("Invalid flags string size ", fileFlags.size(),
|
||||
"in ", keyFlags));
|
||||
Json::Value const& entry = val[ii];
|
||||
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
|
||||
testEntry(entry.size() == 2, "JSON array size invalid.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value const& entryName = entry[0u];
|
||||
Json::Value const& entryFlags = entry[1u];
|
||||
if (testEntry(entryName.isString(),
|
||||
"JSON value for name is not a string.") ||
|
||||
testEntry(entryFlags.isString(),
|
||||
"JSON value for flags is not a string.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name = entryName.asString();
|
||||
std::string flags = entryFlags.asString();
|
||||
if (testEntry(flags.size() == 2, "Invalid flags string size")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmFileTime fileTime;
|
||||
if (!fileTime.Load(fileName)) {
|
||||
LogInfoError(cmStrCat("The source file ", this->MessagePath(fileName),
|
||||
if (!fileTime.Load(name)) {
|
||||
LogInfoError(cmStrCat("The source file ", this->MessagePath(name),
|
||||
" does not exist."));
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(fileName);
|
||||
SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(name);
|
||||
sourceHandle->FileTime = fileTime;
|
||||
sourceHandle->IsHeader = false;
|
||||
sourceHandle->Moc = (fileFlags[0] == 'M');
|
||||
sourceHandle->Uic = (fileFlags[1] == 'U');
|
||||
BaseEval().Sources.emplace(std::move(fileName), std::move(sourceHandle));
|
||||
sourceHandle->Moc = (flags[0] == 'M');
|
||||
sourceHandle->Uic = (flags[1] == 'U');
|
||||
BaseEval().Sources.emplace(std::move(name), std::move(sourceHandle));
|
||||
}
|
||||
}
|
||||
|
||||
// Init derived information
|
||||
// ------------------------
|
||||
|
||||
// -- Init derived information
|
||||
// Moc variables
|
||||
if (MocConst().Enabled) {
|
||||
// Mocs compilation file
|
||||
MocConst_.CompFileAbs = AbsoluteBuildPath("mocs_compilation.cpp");
|
||||
|
||||
// Moc predefs file
|
||||
if (!MocConst_.PredefsCmd.empty()) {
|
||||
std::string pathRel;
|
||||
if (BaseConst_.MultiConfig) {
|
||||
pathRel = cmStrCat("moc_predefs_", InfoConfig(), ".h");
|
||||
} else {
|
||||
pathRel = "moc_predefs.h";
|
||||
}
|
||||
MocConst_.PredefsFileAbs = AbsoluteBuildPath(pathRel);
|
||||
}
|
||||
|
||||
// Compose moc includes list
|
||||
{
|
||||
// Compute framework paths
|
||||
@@ -2031,11 +2006,11 @@ void cmQtAutoMocUic::SettingsFileRead()
|
||||
if (UicConst().Enabled) {
|
||||
cryptoHash.Initialize();
|
||||
cha(UicConst().Executable);
|
||||
std::for_each(UicConst().TargetOptions.begin(),
|
||||
UicConst().TargetOptions.end(), cha);
|
||||
for (const auto& item : UicConst().Options) {
|
||||
std::for_each(UicConst().Options.begin(), UicConst().Options.end(), cha);
|
||||
for (const auto& item : UicConst().UiFiles) {
|
||||
cha(item.first);
|
||||
std::for_each(item.second.begin(), item.second.end(), cha);
|
||||
auto const& opts = item.second.Options;
|
||||
std::for_each(opts.begin(), opts.end(), cha);
|
||||
}
|
||||
SettingsStringUic_ = cryptoHash.FinalizeHex();
|
||||
}
|
||||
@@ -2080,7 +2055,7 @@ bool cmQtAutoMocUic::SettingsFileWrite()
|
||||
if (Log().Verbose()) {
|
||||
Log().Info(
|
||||
GenT::GEN,
|
||||
cmStrCat("Writing settings file ", MessagePath(SettingsFile_)));
|
||||
cmStrCat("Writing the settings file ", MessagePath(SettingsFile_)));
|
||||
}
|
||||
// Compose settings file content
|
||||
std::string content;
|
||||
|
||||
+20
-25
@@ -25,8 +25,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
/** \class cmQtAutoMocUic
|
||||
* \brief AUTOMOC and AUTOUIC generator
|
||||
*/
|
||||
@@ -42,17 +40,21 @@ public:
|
||||
public:
|
||||
// -- Types
|
||||
|
||||
/** Include string with sub parts. */
|
||||
struct IncludeKeyT
|
||||
{
|
||||
IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
|
||||
|
||||
std::string Key; // Full include string
|
||||
std::string Dir; // Include directory
|
||||
std::string Base; // Base part of the include file name
|
||||
};
|
||||
|
||||
/** Search key plus regular expression pair. */
|
||||
struct KeyExpT
|
||||
{
|
||||
KeyExpT() = default;
|
||||
|
||||
KeyExpT(const char* key, const char* exp)
|
||||
: Key(key)
|
||||
, Exp(exp)
|
||||
{
|
||||
}
|
||||
|
||||
KeyExpT(std::string key, std::string const& exp)
|
||||
: Key(std::move(key))
|
||||
, Exp(exp)
|
||||
@@ -63,16 +65,6 @@ public:
|
||||
cmsys::RegularExpression Exp;
|
||||
};
|
||||
|
||||
/** Include string with sub parts. */
|
||||
struct IncludeKeyT
|
||||
{
|
||||
IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
|
||||
|
||||
std::string Key; // Full include string
|
||||
std::string Dir; // Include directory
|
||||
std::string Base; // Base part of the include file name
|
||||
};
|
||||
|
||||
/** Source file parsing cache. */
|
||||
class ParseCacheT
|
||||
{
|
||||
@@ -169,6 +161,7 @@ public:
|
||||
// - Config
|
||||
bool MultiConfig = false;
|
||||
unsigned int QtVersionMajor = 4;
|
||||
unsigned int ThreadCount = 0;
|
||||
// - Directories
|
||||
std::string AutogenBuildDir;
|
||||
std::string AutogenIncludeDir;
|
||||
@@ -251,6 +244,12 @@ public:
|
||||
/** Uic settings. */
|
||||
class UicSettingsT
|
||||
{
|
||||
public:
|
||||
struct UiFile
|
||||
{
|
||||
std::vector<std::string> Options;
|
||||
};
|
||||
|
||||
public:
|
||||
UicSettingsT();
|
||||
~UicSettingsT();
|
||||
@@ -267,8 +266,8 @@ public:
|
||||
cmFileTime ExecutableTime;
|
||||
std::string Executable;
|
||||
std::unordered_set<std::string> SkipList;
|
||||
std::vector<std::string> TargetOptions;
|
||||
std::map<std::string, std::vector<std::string>> Options;
|
||||
std::vector<std::string> Options;
|
||||
std::unordered_map<std::string, UiFile> UiFiles;
|
||||
std::vector<std::string> SearchPaths;
|
||||
cmsys::RegularExpression RegExpInclude;
|
||||
};
|
||||
@@ -523,10 +522,8 @@ public:
|
||||
std::string CollapseFullPathTS(std::string const& path) const;
|
||||
|
||||
private:
|
||||
// -- Utility accessors
|
||||
Logger const& Log() const { return Logger_; }
|
||||
// -- Abstract processing interface
|
||||
bool Init(cmMakefile* makefile) override;
|
||||
bool InitFromInfo() override;
|
||||
void InitJobs();
|
||||
bool Process() override;
|
||||
// -- Settings file
|
||||
@@ -541,8 +538,6 @@ private:
|
||||
bool CreateDirectories();
|
||||
|
||||
private:
|
||||
// -- Utility
|
||||
Logger Logger_;
|
||||
// -- Settings
|
||||
BaseSettingsT BaseConst_;
|
||||
BaseEvalT BaseEval_;
|
||||
|
||||
+26
-90
@@ -6,7 +6,6 @@
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmDuration.h"
|
||||
#include "cmFileLockResult.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmProcessOutput.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@@ -16,112 +15,49 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
cmQtAutoRcc::cmQtAutoRcc() = default;
|
||||
cmQtAutoRcc::cmQtAutoRcc()
|
||||
: cmQtAutoGenerator(GenT::RCC)
|
||||
{
|
||||
}
|
||||
cmQtAutoRcc::~cmQtAutoRcc() = default;
|
||||
|
||||
bool cmQtAutoRcc::Init(cmMakefile* makefile)
|
||||
bool cmQtAutoRcc::InitFromInfo()
|
||||
{
|
||||
// -- Utility lambdas
|
||||
auto InfoGet = [makefile](cm::string_view key) {
|
||||
return makefile->GetSafeDefinition(std::string(key));
|
||||
};
|
||||
auto InfoGetList =
|
||||
[makefile](cm::string_view key) -> std::vector<std::string> {
|
||||
return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
|
||||
};
|
||||
auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
|
||||
if (const char* valueConf =
|
||||
makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
|
||||
return std::string(valueConf);
|
||||
}
|
||||
return makefile->GetSafeDefinition(std::string(key));
|
||||
};
|
||||
auto InfoGetConfigList =
|
||||
[&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
|
||||
return cmExpandedList(InfoGetConfig(key));
|
||||
};
|
||||
auto LogInfoError = [this](cm::string_view msg) -> bool {
|
||||
this->Log().Error(
|
||||
GenT::RCC, cmStrCat("In ", MessagePath(this->InfoFile()), ":\n", msg));
|
||||
// -- Required settings
|
||||
if (!InfoBool("MULTI_CONFIG", MultiConfig_, true) ||
|
||||
!InfoString("BUILD_DIR", AutogenBuildDir_, true) ||
|
||||
!InfoStringConfig("INCLUDE_DIR", IncludeDir_, true) ||
|
||||
!InfoString("RCC_EXECUTABLE", RccExecutable_, true) ||
|
||||
!InfoArray("RCC_LIST_OPTIONS", RccListOptions_, false) ||
|
||||
!InfoString("LOCK_FILE", LockFile_, true) ||
|
||||
!InfoStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
|
||||
!InfoString("SOURCE", QrcFile_, true) ||
|
||||
!InfoString("OUTPUT_CHECKSUM", RccPathChecksum_, true) ||
|
||||
!InfoString("OUTPUT_NAME", RccFileName_, true) ||
|
||||
!InfoArray("OPTIONS", Options_, false) ||
|
||||
!InfoArray("INPUTS", Inputs_, false)) {
|
||||
return false;
|
||||
};
|
||||
|
||||
// -- Read info file
|
||||
if (!makefile->ReadListFile(InfoFile())) {
|
||||
return LogInfoError("File processing failed.");
|
||||
}
|
||||
|
||||
// - Configurations
|
||||
Logger_.RaiseVerbosity(InfoGet("ARCC_VERBOSITY"));
|
||||
MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG");
|
||||
|
||||
// - Directories
|
||||
ProjectDirsRef().Source = InfoGet("ARCC_CMAKE_SOURCE_DIR");
|
||||
ProjectDirsRef().Binary = InfoGet("ARCC_CMAKE_BINARY_DIR");
|
||||
AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR");
|
||||
if (AutogenBuildDir_.empty()) {
|
||||
return LogInfoError("Build directory empty.");
|
||||
}
|
||||
|
||||
IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR");
|
||||
if (IncludeDir_.empty()) {
|
||||
return LogInfoError("Include directory empty.");
|
||||
}
|
||||
|
||||
// - Rcc executable
|
||||
RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
|
||||
if (!RccExecutableTime_.Load(RccExecutable_)) {
|
||||
return LogInfoError(cmStrCat(
|
||||
"The rcc executable ", MessagePath(RccExecutable_), " does not exist."));
|
||||
}
|
||||
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
|
||||
|
||||
// - Job
|
||||
LockFile_ = InfoGet("ARCC_LOCK_FILE");
|
||||
QrcFile_ = InfoGet("ARCC_SOURCE");
|
||||
// -- Derive information
|
||||
QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_);
|
||||
QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_);
|
||||
RccPathChecksum_ = InfoGet("ARCC_OUTPUT_CHECKSUM");
|
||||
RccFileName_ = InfoGet("ARCC_OUTPUT_NAME");
|
||||
Options_ = InfoGetConfigList("ARCC_OPTIONS");
|
||||
Inputs_ = InfoGetList("ARCC_INPUTS");
|
||||
|
||||
// - Settings file
|
||||
SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE");
|
||||
|
||||
// - Validity checks
|
||||
if (LockFile_.empty()) {
|
||||
return LogInfoError("Lock file name missing.");
|
||||
}
|
||||
if (SettingsFile_.empty()) {
|
||||
return LogInfoError("Settings file name missing.");
|
||||
}
|
||||
if (AutogenBuildDir_.empty()) {
|
||||
return LogInfoError("Autogen build directory missing.");
|
||||
}
|
||||
if (RccExecutable_.empty()) {
|
||||
return LogInfoError("rcc executable missing.");
|
||||
}
|
||||
if (QrcFile_.empty()) {
|
||||
return LogInfoError("rcc input file missing.");
|
||||
}
|
||||
if (RccFileName_.empty()) {
|
||||
return LogInfoError("rcc output file missing.");
|
||||
}
|
||||
|
||||
// Init derived information
|
||||
// ------------------------
|
||||
|
||||
RccFilePublic_ =
|
||||
cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_);
|
||||
|
||||
// Compute rcc output file name
|
||||
// rcc output file name
|
||||
if (IsMultiConfig()) {
|
||||
RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput());
|
||||
} else {
|
||||
RccFileOutput_ = RccFilePublic_;
|
||||
}
|
||||
|
||||
// -- Checks
|
||||
if (!RccExecutableTime_.Load(RccExecutable_)) {
|
||||
return LogInfoError(cmStrCat(
|
||||
"The rcc executable ", MessagePath(RccExecutable_), " does not exist."));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
/** \class cmQtAutoRcc
|
||||
* \brief AUTORCC generator
|
||||
*/
|
||||
@@ -28,12 +26,11 @@ public:
|
||||
|
||||
private:
|
||||
// -- Utility
|
||||
Logger const& Log() const { return Logger_; }
|
||||
bool IsMultiConfig() const { return MultiConfig_; }
|
||||
std::string MultiConfigOutput() const;
|
||||
|
||||
// -- Abstract processing interface
|
||||
bool Init(cmMakefile* makefile) override;
|
||||
bool InitFromInfo() override;
|
||||
bool Process() override;
|
||||
// -- Settings file
|
||||
bool SettingsFileRead();
|
||||
@@ -47,8 +44,6 @@ private:
|
||||
bool GenerateWrapper();
|
||||
|
||||
private:
|
||||
// -- Logging
|
||||
Logger Logger_;
|
||||
// -- Config settings
|
||||
bool MultiConfig_ = false;
|
||||
// -- Directories
|
||||
|
||||
Reference in New Issue
Block a user