mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-05 14:49:39 -06:00
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
This commit is contained in:
@@ -1,15 +1,56 @@
|
|||||||
/* 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(
|
|||||||
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()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
|||||||
|
|
||||||
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()
|
|||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
#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:
|
|||||||
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 @@
|
|||||||
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,
|
|||||||
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()
|
|||||||
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()
|
|||||||
|
|
||||||
// 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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
// 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 @@
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
std::string& errorMessage);
|
std::string& errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
cmQtAutoGenGlobalInitializer* GlobalInitializer;
|
||||||
cmGeneratorTarget* Target;
|
cmGeneratorTarget* Target;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
@@ -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:
|
|||||||
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user