CMake/Source/cmQtAutoGenInitializer.h
Joerg Bornemann aebfbcaa46 AutoGen: Use depfiles for the XXX_autogen ninja targets
The XXX_autogen targets are implemented as utility commands, which
means they always run, even if there weren't any changes.

For the Ninja generator and Qt >= 5.15 we're taking a different
approach: This commit adds custom commands that create
XXX_autogen/timestamp files. Those custom commands have a depfile
assigned that is generated from the depfiles that were created by moc.

The XXX_autogen targets merely wrap the XXX_autogen/timestamp custom
commands.

Fixes: #18749
2020-01-28 11:16:11 -05:00

254 lines
6.6 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmQtAutoGenInitializer_h
#define cmQtAutoGenInitializer_h
#include "cmConfigure.h" // IWYU pragma: keep
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cm/string_view>
#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmLocalGenerator;
class cmMakefile;
class cmQtAutoGenGlobalInitializer;
class cmSourceFile;
class cmTarget;
/** \class cmQtAutoGenerator
* \brief Initializes the QtAutoGen generators
*/
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
{
public:
std::string LockFile;
std::string QrcFile;
std::string QrcName;
std::string QrcPathChecksum;
std::string InfoFile;
ConfigString SettingsFile;
std::string OutputFile;
bool Generated = false;
bool Unique = false;
std::vector<std::string> Options;
std::vector<std::string> Resources;
};
/** moc and/or uic file. */
struct MUFile
{
std::string FullPath;
cmSourceFile* SF = nullptr;
bool Generated = false;
bool SkipMoc = false;
bool SkipUic = false;
bool MocIt = false;
bool UicIt = false;
};
using MUFileHandle = std::unique_ptr<MUFile>;
/** Abstract moc/uic/rcc generator variables base class. */
struct GenVarsT
{
bool Enabled = false;
// Generator type/name
GenT Gen;
cm::string_view GenNameUpper;
// Executable
std::string ExecutableTargetName;
cmGeneratorTarget* ExecutableTarget = nullptr;
std::string Executable;
CompilerFeaturesHandle ExecutableFeatures;
GenVarsT(GenT gen)
: Gen(gen)
, GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){};
};
public:
/** @return The detected Qt version and the required Qt major version. */
static std::pair<IntegerVersion, unsigned int> GetQtVersion(
cmGeneratorTarget const* genTarget);
cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
cmGeneratorTarget* genTarget,
IntegerVersion const& qtVersion, bool mocEnabled,
bool uicEnabled, bool rccEnabled,
bool globalAutogenTarget, bool globalAutoRccTarget);
bool InitCustomTargets();
bool SetupCustomTargets();
private:
/** If moc or uic is enabled, the autogen target will be generated. */
bool MocOrUicEnabled() const
{
return (this->Moc.Enabled || this->Uic.Enabled);
}
bool InitMoc();
bool InitUic();
bool InitRcc();
bool InitScanFiles();
bool InitAutogenTarget();
bool InitRccTargets();
bool SetupWriteAutogenInfo();
bool SetupWriteRccInfo();
cmSourceFile* RegisterGeneratedSource(std::string const& filename);
cmSourceFile* AddGeneratedSource(std::string const& filename,
GenVarsT const& genVars,
bool prepend = false);
void AddToSourceGroup(std::string const& fileName,
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;
private:
cmQtAutoGenGlobalInitializer* GlobalInitializer = nullptr;
cmGeneratorTarget* GenTarget = nullptr;
cmGlobalGenerator* GlobalGen = nullptr;
cmLocalGenerator* LocalGen = nullptr;
cmMakefile* Makefile = nullptr;
cmFilePathChecksum const PathCheckSum;
// -- Configuration
IntegerVersion QtVersion;
unsigned int Verbosity = 0;
bool MultiConfig = false;
bool CMP0071Accept = false;
bool CMP0071Warn = false;
bool CMP0100Accept = false;
bool CMP0100Warn = false;
std::string ConfigDefault;
std::vector<std::string> ConfigsList;
std::string TargetsFolder;
/** Common directories. */
struct
{
std::string Info;
std::string Build;
std::string Work;
ConfigString Include;
std::string IncludeGenExp;
} Dir;
/** Autogen target variables. */
struct
{
std::string Name;
bool GlobalTarget = false;
// Settings
unsigned int Parallel = 1;
// Configuration files
std::string InfoFile;
ConfigString SettingsFile;
ConfigString ParseCacheFile;
// Dependencies
bool DependOrigin = false;
std::set<std::string> DependFiles;
std::set<cmTarget*> DependTargets;
std::string DepFile;
std::string DepFileRuleName;
// Sources to process
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
std::vector<MUFile*> FilesGenerated;
std::vector<cmSourceFile*> CMP0100HeadersWarn;
} AutogenTarget;
/** moc variables. */
struct MocT : public GenVarsT
{
MocT()
: GenVarsT(GenT::MOC){};
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;
} Uic;
/** rcc variables. */
struct RccT : public GenVarsT
{
RccT()
: GenVarsT(GenT::RCC){};
bool GlobalTarget = false;
std::vector<Qrc> Qrcs;
} Rcc;
};
#endif