Commit 84bdae88 authored by Sebastian Holtermann's avatar Sebastian Holtermann
Browse files

Autogen: Compute variables in Init stage instead of Setup stage

parent 8e0d7027
......@@ -317,17 +317,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
}
// Add moc compilation to generated files list
if (this->Moc.Enabled) {
std::string mocsComp = this->DirBuild + "/mocs_compilation.cpp";
this->AddGeneratedSource(mocsComp, GeneratorT::MOC);
autogenProvides.push_back(std::move(mocsComp));
if (this->Moc.Enabled && !InitCustomTargetsMoc()) {
return false;
}
// Add autogen includes directory to the origin target INCLUDE_DIRECTORIES
if (this->Moc.Enabled || this->Uic.Enabled ||
(this->Rcc.Enabled && this->MultiConfig)) {
this->Target->AddIncludeDirectory(this->DirInclude, true);
if (this->Uic.Enabled && !InitCustomTargetsUic()) {
return false;
}
if (this->Uic.Enabled && !InitCustomTargetsRcc()) {
return false;
}
// Acquire rcc executable and features
......@@ -337,6 +334,17 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
}
// Add autogen includes directory to the origin target INCLUDE_DIRECTORIES
if (this->Moc.Enabled || this->Uic.Enabled ||
(this->Rcc.Enabled && this->MultiConfig)) {
this->Target->AddIncludeDirectory(this->DirInclude, true);
}
if (this->Moc.Enabled) {
this->AddGeneratedSource(this->Moc.MocsCompilation, GeneratorT::MOC);
autogenProvides.push_back(this->Moc.MocsCompilation);
}
// Extract relevant source files
std::vector<std::string> generatedSources;
std::vector<std::string> generatedHeaders;
......@@ -838,6 +846,159 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
return true;
}
bool cmQtAutoGenInitializer::InitCustomTargetsMoc()
{
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
cmMakefile* makefile = this->Target->Target->GetMakefile();
// Add moc compilation to generated files list
this->Moc.MocsCompilation = this->DirBuild;
this->Moc.MocsCompilation += "/mocs_compilation.cpp";
// Moc predefs command
if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
this->QtVersionGreaterOrEqual(5, 8)) {
this->Moc.PredefsCmd =
makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
}
// Moc includes and compile definitions
{
auto GetIncludeDirs = [this,
localGen](std::string const& cfg) -> std::string {
// Get the include dirs for this target, without stripping the implicit
// include dirs off, see
// https://gitlab.kitware.com/cmake/cmake/issues/13667
std::vector<std::string> dirs;
localGen->GetIncludeDirectories(dirs, this->Target, "CXX", cfg, false);
return cmJoin(dirs, ";");
};
// Default configuration include directories
this->Moc.Includes = GetIncludeDirs(this->ConfigDefault);
// Other configuration settings
for (std::string const& cfg : this->ConfigsList) {
std::string configIncludeDirs = GetIncludeDirs(cfg);
if (configIncludeDirs != this->Moc.Includes) {
this->Moc.ConfigIncludes[cfg] = std::move(configIncludeDirs);
}
}
}
// Moc compile definitions
{
auto GetCompileDefinitions =
[this, localGen](std::string const& cfg) -> std::string {
std::set<std::string> defines;
localGen->AddCompileDefinitions(defines, this->Target, cfg, "CXX");
return cmJoin(defines, ";");
};
// Default configuration defines
this->Moc.Defines = GetCompileDefinitions(this->ConfigDefault);
// Other configuration defines
for (std::string const& cfg : this->ConfigsList) {
std::string configCompileDefs = GetCompileDefinitions(cfg);
if (configCompileDefs != this->Moc.Defines) {
this->Moc.ConfigDefines[cfg] = std::move(configCompileDefs);
}
}
}
// Moc executable
if (!GetMocExecutable()) {
return false;
}
return true;
}
bool cmQtAutoGenInitializer::InitCustomTargetsUic()
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
// Uic search paths
{
std::string const usp =
this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
cmSystemTools::ExpandListArgument(usp, this->Uic.SearchPaths);
std::string const srcDir = makefile->GetCurrentSourceDirectory();
for (std::string& path : this->Uic.SearchPaths) {
path = cmSystemTools::CollapseFullPath(path, srcDir);
}
}
}
// Uic target options
{
auto UicGetOpts = [this](std::string const& cfg) -> std::string {
std::vector<std::string> opts;
this->Target->GetAutoUicOptions(opts, cfg);
return cmJoin(opts, ";");
};
// Default settings
this->Uic.Options = UicGetOpts(this->ConfigDefault);
// Configuration specific settings
for (std::string const& cfg : this->ConfigsList) {
std::string const configUicOpts = UicGetOpts(cfg);
if (configUicOpts != this->Uic.Options) {
this->Uic.ConfigOptions[cfg] = configUicOpts;
}
}
}
// .ui files skip and options
{
std::string const uiExt = "ui";
std::string pathError;
for (cmSourceFile* sf : makefile->GetSourceFiles()) {
// sf->GetExtension() is only valid after sf->GetFullPath() ...
// Since we're iterating over source files that might be not in the
// target we need to check for path errors (not existing files).
std::string const& fPath = sf->GetFullPath(&pathError);
if (!pathError.empty()) {
pathError.clear();
continue;
}
if (sf->GetExtension() == uiExt) {
std::string const absFile = cmSystemTools::GetRealPath(fPath);
// Check if the .ui file should be skipped
if (sf->GetPropertyAsBool("SKIP_AUTOUIC") ||
sf->GetPropertyAsBool("SKIP_AUTOGEN")) {
this->Uic.Skip.insert(absFile);
}
// Check if the .ui file has uic options
std::string const uicOpts = sf->GetSafeProperty("AUTOUIC_OPTIONS");
if (!uicOpts.empty()) {
// Check if file isn't skipped
if (this->Uic.Skip.count(absFile) == 0) {
this->Uic.FileFiles.push_back(absFile);
std::vector<std::string> optsVec;
cmSystemTools::ExpandListArgument(uicOpts, optsVec);
this->Uic.FileOptions.push_back(std::move(optsVec));
}
}
}
}
}
if (!GetUicExecutable()) {
return false;
}
return true;
}
bool cmQtAutoGenInitializer::InitCustomTargetsRcc()
{
if (!GetRccExecutable()) {
return false;
}
return true;
}
bool cmQtAutoGenInitializer::SetupCustomTargets()
{
// Create info directory on demand
......@@ -850,12 +1011,6 @@ bool cmQtAutoGenInitializer::SetupCustomTargets()
// Generate autogen target info file
if (this->Moc.Enabled || this->Uic.Enabled) {
if (this->Moc.Enabled) {
this->SetupCustomTargetsMoc();
}
if (this->Uic.Enabled) {
this->SetupCustomTargetsUic();
}
// Write autogen target info files
if (!this->SetupWriteAutogenInfo()) {
return false;
......@@ -1060,146 +1215,6 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
return true;
}
bool cmQtAutoGenInitializer::SetupCustomTargetsMoc()
{
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
cmMakefile* makefile = this->Target->Target->GetMakefile();
// Moc predefs command
if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
this->QtVersionGreaterOrEqual(5, 8)) {
this->Moc.PredefsCmd =
makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
}
// Moc includes and compile definitions
{
auto GetIncludeDirs = [this,
localGen](std::string const& cfg) -> std::string {
// Get the include dirs for this target, without stripping the implicit
// include dirs off, see
// https://gitlab.kitware.com/cmake/cmake/issues/13667
std::vector<std::string> dirs;
localGen->GetIncludeDirectories(dirs, this->Target, "CXX", cfg, false);
return cmJoin(dirs, ";");
};
// Default configuration include directories
this->Moc.Includes = GetIncludeDirs(this->ConfigDefault);
// Other configuration settings
for (std::string const& cfg : this->ConfigsList) {
std::string configIncludeDirs = GetIncludeDirs(cfg);
if (configIncludeDirs != this->Moc.Includes) {
this->Moc.ConfigIncludes[cfg] = std::move(configIncludeDirs);
}
}
}
// Moc compile definitions
{
auto GetCompileDefinitions =
[this, localGen](std::string const& cfg) -> std::string {
std::set<std::string> defines;
localGen->AddCompileDefinitions(defines, this->Target, cfg, "CXX");
return cmJoin(defines, ";");
};
// Default configuration defines
this->Moc.Defines = GetCompileDefinitions(this->ConfigDefault);
// Other configuration defines
for (std::string const& cfg : this->ConfigsList) {
std::string configCompileDefs = GetCompileDefinitions(cfg);
if (configCompileDefs != this->Moc.Defines) {
this->Moc.ConfigDefines[cfg] = std::move(configCompileDefs);
}
}
}
// Moc executable
if (!GetMocExecutable()) {
return false;
}
return true;
}
bool cmQtAutoGenInitializer::SetupCustomTargetsUic()
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
// Uic search paths
{
std::string const usp =
this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
cmSystemTools::ExpandListArgument(usp, this->Uic.SearchPaths);
std::string const srcDir = makefile->GetCurrentSourceDirectory();
for (std::string& path : this->Uic.SearchPaths) {
path = cmSystemTools::CollapseFullPath(path, srcDir);
}
}
}
// Uic target options
{
auto UicGetOpts = [this](std::string const& cfg) -> std::string {
std::vector<std::string> opts;
this->Target->GetAutoUicOptions(opts, cfg);
return cmJoin(opts, ";");
};
// Default settings
this->Uic.Options = UicGetOpts(this->ConfigDefault);
// Configuration specific settings
for (std::string const& cfg : this->ConfigsList) {
std::string const configUicOpts = UicGetOpts(cfg);
if (configUicOpts != this->Uic.Options) {
this->Uic.ConfigOptions[cfg] = configUicOpts;
}
}
}
// .ui files skip and options
{
std::string const uiExt = "ui";
std::string pathError;
for (cmSourceFile* sf : makefile->GetSourceFiles()) {
// sf->GetExtension() is only valid after sf->GetFullPath() ...
// Since we're iterating over source files that might be not in the
// target we need to check for path errors (not existing files).
std::string const& fPath = sf->GetFullPath(&pathError);
if (!pathError.empty()) {
pathError.clear();
continue;
}
if (sf->GetExtension() == uiExt) {
std::string const absFile = cmSystemTools::GetRealPath(fPath);
// Check if the .ui file should be skipped
if (sf->GetPropertyAsBool("SKIP_AUTOUIC") ||
sf->GetPropertyAsBool("SKIP_AUTOGEN")) {
this->Uic.Skip.insert(absFile);
}
// Check if the .ui file has uic options
std::string const uicOpts = sf->GetSafeProperty("AUTOUIC_OPTIONS");
if (!uicOpts.empty()) {
// Check if file isn't skipped
if (this->Uic.Skip.count(absFile) == 0) {
this->Uic.FileFiles.push_back(absFile);
std::vector<std::string> optsVec;
cmSystemTools::ExpandListArgument(uicOpts, optsVec);
this->Uic.FileOptions.push_back(std::move(optsVec));
}
}
}
}
}
if (!GetUicExecutable()) {
return false;
}
return true;
}
void cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
GeneratorT genType)
{
......
......@@ -54,8 +54,9 @@ public:
bool SetupCustomTargets();
private:
bool SetupCustomTargetsMoc();
bool SetupCustomTargetsUic();
bool InitCustomTargetsMoc();
bool InitCustomTargetsUic();
bool InitCustomTargetsRcc();
bool SetupWriteAutogenInfo();
bool SetupWriteRccInfo();
......@@ -75,7 +76,7 @@ private:
private:
cmGeneratorTarget* Target;
bool MultiConfig;
bool MultiConfig = false;
// Qt
std::string QtVersionMajor;
std::string QtVersionMinor;
......@@ -101,7 +102,7 @@ private:
// Moc
struct
{
bool Enabled;
bool Enabled = false;
std::string Executable;
std::string PredefsCmd;
std::set<std::string> Skip;
......@@ -109,11 +110,12 @@ private:
std::map<std::string, std::string> ConfigIncludes;
std::string Defines;
std::map<std::string, std::string> ConfigDefines;
std::string MocsCompilation;
} Moc;
// Uic
struct
{
bool Enabled;
bool Enabled = false;
std::string Executable;
std::set<std::string> Skip;
std::vector<std::string> SearchPaths;
......@@ -125,7 +127,7 @@ private:
// Rcc
struct
{
bool Enabled;
bool Enabled = false;
std::string Executable;
std::vector<std::string> ListOptions;
std::vector<Qrc> Qrcs;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment