Commit 3baa817c authored by Sebastian Holtermann's avatar Sebastian Holtermann
Browse files

Autogen: Add support for global ``autogen`` and ``autorcc`` targets

This teaches CMake the variables

- CMAKE_GLOBAL_AUTOGEN_TARGET
- CMAKE_GLOBAL_AUTOGEN_TARGET_NAME
- CMAKE_GLOBAL_AUTORCC_TARGET
- CMAKE_GLOBAL_AUTORCC_TARGET_NAME

which control the generation of global
``autogen`` and ``autorcc`` targets.

Closes #17721
parent 3327d3bb
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenGlobalInitializer.h" #include "cmQtAutoGenGlobalInitializer.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenInitializer.h"
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorTarget.h" #include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
#include "cmQtAutoGenInitializer.h" #include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include <memory>
#include <utility>
cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
std::vector<cmLocalGenerator*> const& localGenerators) std::vector<cmLocalGenerator*> const& localGenerators)
{ {
for (cmLocalGenerator* localGen : localGenerators) { for (cmLocalGenerator* localGen : localGenerators) {
// Detect global autogen and autorcc target names
bool globalAutoGenTarget = false;
bool globalAutoRccTarget = false;
{
cmMakefile* makefile = localGen->GetMakefile();
// Detect global autogen target name
if (cmSystemTools::IsOn(
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
std::string targetName =
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME");
if (targetName.empty()) {
targetName = "autogen";
}
GlobalAutoGenTargets_.emplace(localGen, std::move(targetName));
globalAutoGenTarget = true;
}
// Detect global autorcc target name
if (cmSystemTools::IsOn(
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
std::string targetName =
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME");
if (targetName.empty()) {
targetName = "autorcc";
}
GlobalAutoRccTargets_.emplace(localGen, std::move(targetName));
globalAutoRccTarget = true;
}
}
// Find targets that require AUTOMOC/UIC/RCC processing // Find targets that require AUTOMOC/UIC/RCC processing
for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) { for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
// Process only certain target types // Process only certain target types
...@@ -39,7 +80,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( ...@@ -39,7 +80,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) { if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) {
// Create autogen target initializer // Create autogen target initializer
Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>( Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
target, moc, uic, rcc, qtVersion)); this, target, qtVersion, moc, uic, rcc, globalAutoGenTarget,
globalAutoRccTarget));
} }
} }
} }
...@@ -50,6 +92,58 @@ cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer() ...@@ -50,6 +92,58 @@ cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer()
{ {
} }
void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
cmLocalGenerator* localGen, std::string const& name,
std::string const& comment)
{
// Test if the target already exists
if (localGen->FindGeneratorTargetToUse(name) == nullptr) {
cmMakefile* makefile = localGen->GetMakefile();
// Create utility target
cmTarget* target = makefile->AddUtilityCommand(
name, cmMakefile::TargetOrigin::Generator, true,
makefile->GetHomeOutputDirectory().c_str() /*work dir*/,
std::vector<std::string>() /*output*/,
std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
comment.c_str());
localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen));
// Set FOLDER property in the target
{
char const* folder =
makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
if (folder != nullptr) {
target->SetProperty("FOLDER", folder);
}
}
}
}
void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
cmLocalGenerator* localGen, std::string const& targetName)
{
auto it = GlobalAutoGenTargets_.find(localGen);
if (it != GlobalAutoGenTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
target->Target->AddUtility(targetName, localGen->GetMakefile());
}
}
}
void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
cmLocalGenerator* localGen, std::string const& targetName)
{
auto it = GlobalAutoRccTargets_.find(localGen);
if (it != GlobalAutoRccTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
target->Target->AddUtility(targetName, localGen->GetMakefile());
}
}
}
bool cmQtAutoGenGlobalInitializer::generate() bool cmQtAutoGenGlobalInitializer::generate()
{ {
return (InitializeCustomTargets() && SetupCustomTargets()); return (InitializeCustomTargets() && SetupCustomTargets());
...@@ -57,8 +151,23 @@ bool cmQtAutoGenGlobalInitializer::generate() ...@@ -57,8 +151,23 @@ bool cmQtAutoGenGlobalInitializer::generate()
bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
{ {
for (auto& autoGen : Initializers_) { // Initialize global autogen targets
if (!autoGen->InitCustomTargets()) { {
std::string const comment = "Global AUTOGEN target";
for (auto const& pair : GlobalAutoGenTargets_) {
GetOrCreateGlobalTarget(pair.first, pair.second, comment);
}
}
// Initialize global autorcc targets
{
std::string const comment = "Global AUTORCC target";
for (auto const& pair : GlobalAutoRccTargets_) {
GetOrCreateGlobalTarget(pair.first, pair.second, comment);
}
}
// Initialize per target autogen targets
for (auto& initializer : Initializers_) {
if (!initializer->InitCustomTargets()) {
return false; return false;
} }
} }
...@@ -67,8 +176,8 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() ...@@ -67,8 +176,8 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
bool cmQtAutoGenGlobalInitializer::SetupCustomTargets() bool cmQtAutoGenGlobalInitializer::SetupCustomTargets()
{ {
for (auto& autoGen : Initializers_) { for (auto& initializer : Initializers_) {
if (!autoGen->SetupCustomTargets()) { if (!initializer->SetupCustomTargets()) {
return false; return false;
} }
} }
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep #include "cmConfigure.h" // IWYU pragma: keep
#include <memory> #include <map>
#include <memory> // IWYU pragma: keep
#include <string>
#include <vector> #include <vector>
class cmLocalGenerator; class cmLocalGenerator;
...@@ -22,11 +24,24 @@ public: ...@@ -22,11 +24,24 @@ public:
bool generate(); bool generate();
private: private:
friend class cmQtAutoGenInitializer;
bool InitializeCustomTargets(); bool InitializeCustomTargets();
bool SetupCustomTargets(); bool SetupCustomTargets();
void GetOrCreateGlobalTarget(cmLocalGenerator* localGen,
std::string const& name,
std::string const& comment);
void AddToGlobalAutoGen(cmLocalGenerator* localGen,
std::string const& targetName);
void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
std::string const& targetName);
private: private:
std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_; std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
}; };
#endif #endif
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenInitializer.h" #include "cmQtAutoGenInitializer.h"
#include "cmQtAutoGen.h" #include "cmQtAutoGen.h"
#include "cmQtAutoGenGlobalInitializer.h"
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
#include "cmCustomCommand.h" #include "cmCustomCommand.h"
...@@ -174,17 +175,19 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, ...@@ -174,17 +175,19 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
return cycle; return cycle;
} }
cmQtAutoGenInitializer::cmQtAutoGenInitializer(cmGeneratorTarget* target, cmQtAutoGenInitializer::cmQtAutoGenInitializer(
bool mocEnabled, cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target,
bool uicEnabled, IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled,
bool rccEnabled, bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget)
IntegerVersion const& qtVersion) : GlobalInitializer(globalInitializer)
: Target(target) , Target(target)
, QtVersion(qtVersion) , QtVersion(qtVersion)
{ {
AutogenTarget.GlobalTarget = globalAutogenTarget;
Moc.Enabled = mocEnabled; Moc.Enabled = mocEnabled;
Uic.Enabled = uicEnabled; Uic.Enabled = uicEnabled;
Rcc.Enabled = rccEnabled; Rcc.Enabled = rccEnabled;
Rcc.GlobalTarget = globalAutoRccTarget;
} }
bool cmQtAutoGenInitializer::InitCustomTargets() bool cmQtAutoGenInitializer::InitCustomTargets()
...@@ -882,6 +885,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() ...@@ -882,6 +885,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (!this->AutogenTarget.DependFiles.empty()) { if (!this->AutogenTarget.DependFiles.empty()) {
usePRE_BUILD = false; usePRE_BUILD = false;
} }
// Cannot use PRE_BUILD when a global autogen target is in place
if (AutogenTarget.GlobalTarget) {
usePRE_BUILD = false;
}
} }
// Create the autogen target/command // Create the autogen target/command
if (usePRE_BUILD) { if (usePRE_BUILD) {
...@@ -961,6 +968,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() ...@@ -961,6 +968,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Add autogen target to the origin target dependencies // Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile); this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile);
// Add autogen target to the global autogen target dependencies
if (this->AutogenTarget.GlobalTarget) {
this->GlobalInitializer->AddToGlobalAutoGen(localGen,
this->AutogenTarget.Name);
}
} }
return true; return true;
...@@ -1004,7 +1017,7 @@ bool cmQtAutoGenInitializer::InitRccTargets() ...@@ -1004,7 +1017,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
std::string ccComment = "Automatic RCC for "; std::string ccComment = "Automatic RCC for ";
ccComment += FileProjectRelativePath(makefile, qrc.QrcFile); ccComment += FileProjectRelativePath(makefile, qrc.QrcFile);
if (qrc.Generated) { if (qrc.Generated || this->Rcc.GlobalTarget) {
// Create custom rcc target // Create custom rcc target
std::string ccName; std::string ccName;
{ {
...@@ -1035,6 +1048,11 @@ bool cmQtAutoGenInitializer::InitRccTargets() ...@@ -1035,6 +1048,11 @@ bool cmQtAutoGenInitializer::InitRccTargets()
} }
// Add autogen target to the origin target dependencies // Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(ccName, makefile); this->Target->Target->AddUtility(ccName, makefile);
// Add autogen target to the global autogen target dependencies
if (this->Rcc.GlobalTarget) {
this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName);
}
} else { } else {
// Create custom rcc command // Create custom rcc command
{ {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
class cmGeneratorTarget; class cmGeneratorTarget;
class cmTarget; class cmTarget;
class cmQtAutoGenGlobalInitializer;
/// @brief Initializes the QtAutoGen generators /// @brief Initializes the QtAutoGen generators
class cmQtAutoGenInitializer : public cmQtAutoGen class cmQtAutoGenInitializer : public cmQtAutoGen
...@@ -46,9 +47,11 @@ public: ...@@ -46,9 +47,11 @@ public:
public: public:
static IntegerVersion GetQtVersion(cmGeneratorTarget const* target); static IntegerVersion GetQtVersion(cmGeneratorTarget const* target);
cmQtAutoGenInitializer(cmGeneratorTarget* target, bool mocEnabled, cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
cmGeneratorTarget* target,
IntegerVersion const& qtVersion, bool mocEnabled,
bool uicEnabled, bool rccEnabled, bool uicEnabled, bool rccEnabled,
IntegerVersion const& qtVersion); bool globalAutogenTarget, bool globalAutoRccTarget);
bool InitCustomTargets(); bool InitCustomTargets();
bool SetupCustomTargets(); bool SetupCustomTargets();
...@@ -76,6 +79,7 @@ private: ...@@ -76,6 +79,7 @@ private:
std::string& errorMessage); std::string& errorMessage);
private: private:
cmQtAutoGenGlobalInitializer* GlobalInitializer;
cmGeneratorTarget* Target; cmGeneratorTarget* Target;
// Configuration // Configuration
...@@ -100,6 +104,7 @@ private: ...@@ -100,6 +104,7 @@ private:
struct struct
{ {
std::string Name; std::string Name;
bool GlobalTarget = false;
// Settings // Settings
std::string Parallel; std::string Parallel;
// Configuration files // Configuration files
...@@ -148,6 +153,7 @@ private: ...@@ -148,6 +153,7 @@ private:
struct struct
{ {
bool Enabled = false; bool Enabled = false;
bool GlobalTarget = false;
std::string Executable; std::string Executable;
std::vector<std::string> ListOptions; std::vector<std::string> ListOptions;
std::vector<Qrc> Qrcs; 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