mirror of
https://github.com/Kitware/CMake.git
synced 2026-11-06 05:16:58 +00:00
The aggregated translation unit includes the moc output of the target's
headers, and through that the headers themselves, so it may import a C++
module even though nothing autogen writes declares one. Since commit
e5dce1a37e (cmQtAutoGenInitializer: disable C++ module scanning for
autogen sources, 2023-12-11) it has been compiled without a module map,
so such an import fails with "module not found". A project therefore
cannot use an import in any header that moc processes, and cannot work
around it either: the CXX_SCAN_FOR_MODULES source property is set during
generation, after the project has been read, so setting it has no
effect.
Leave that source property of the moc compilation file unset, so that
it is scanned under the same conditions as the target's own sources:
the target property, policy CMP0155, and whether the compiler and the
generator support scanning decide. Setting it to ON instead would
override a target that opts out, and fail generation outright with a
compiler or generator that cannot scan. The remaining autogen sources
keep their current behavior; unlike this one, they do not include
anything the project wrote.
288 lines
8.4 KiB
C++
288 lines
8.4 KiB
C++
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
|
#pragma once
|
|
|
|
#include "cmConfigure.h" // IWYU pragma: keep
|
|
|
|
#include <cstddef>
|
|
#include <limits>
|
|
#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 cmCustomCommandLines;
|
|
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:
|
|
/** rcc job. */
|
|
class Qrc
|
|
{
|
|
public:
|
|
std::string LockFile;
|
|
std::string QrcFile;
|
|
std::string QrcName;
|
|
std::string QrcPathChecksum;
|
|
std::string InfoFile;
|
|
ConfigString SettingsFile;
|
|
ConfigString OutputFile;
|
|
std::string OutputFileGenex;
|
|
bool Generated = false;
|
|
bool Unique = false;
|
|
std::vector<std::string> Options;
|
|
ConfigStrings<std::vector<std::string>> Resources;
|
|
};
|
|
|
|
/** moc and/or uic file. */
|
|
struct MUFile
|
|
{
|
|
std::string FullPath;
|
|
cmSourceFile* SF = nullptr;
|
|
std::vector<size_t> Configs;
|
|
bool Generated = false;
|
|
bool SkipMoc = false;
|
|
bool SkipUic = false;
|
|
bool MocIt = false;
|
|
bool UicIt = false;
|
|
// Memoized GetMocBuildPath() result. Mutable because the info file
|
|
// writer reaches this through const references.
|
|
mutable std::string MocBuildPath;
|
|
};
|
|
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;
|
|
ConfigString Executable;
|
|
ConfigStrings<CompilerFeaturesHandle> ExecutableFeatures;
|
|
|
|
GenVarsT(GenT gen)
|
|
: Gen(gen)
|
|
, GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen))
|
|
{
|
|
}
|
|
};
|
|
|
|
/** @param mocExecutable The file path to the moc executable. Will be used as
|
|
fallback to query the version
|
|
@return The detected Qt version and the required Qt major version. */
|
|
static std::pair<IntegerVersion, unsigned int> GetQtVersion(
|
|
cmGeneratorTarget const* genTarget, std::string mocExecutable);
|
|
|
|
cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
|
|
cmGeneratorTarget* genTarget,
|
|
IntegerVersion 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);
|
|
}
|
|
|
|
/** Whether the CXX compiler targets the MSVC ABI. */
|
|
bool IsMsvcAbi() const;
|
|
|
|
bool InitMoc();
|
|
bool InitUic();
|
|
bool InitRcc();
|
|
|
|
bool InitScanFiles();
|
|
bool InitAutogenTarget();
|
|
bool InitRccTargets();
|
|
|
|
bool SetupWriteAutogenInfo();
|
|
bool SetupWriteRccInfo();
|
|
|
|
/** Whether a generated source is scanned for C++ module dependencies. */
|
|
enum class ModuleScan
|
|
{
|
|
Never, // It imports nothing.
|
|
Always, // It is a unit of a module.
|
|
LikeTarget, // It may import whatever the target's own sources import.
|
|
};
|
|
|
|
cmSourceFile* RegisterGeneratedSource(
|
|
std::string const& filename, ModuleScan moduleScan = ModuleScan::Never);
|
|
cmSourceFile* AddGeneratedSource(std::string const& filename,
|
|
GenVarsT const& genVars,
|
|
bool prepend = false,
|
|
ModuleScan moduleScan = ModuleScan::Never);
|
|
void AddGeneratedSource(ConfigString const& filename,
|
|
GenVarsT const& genVars, bool prepend = false,
|
|
ModuleScan moduleScan = ModuleScan::Never);
|
|
void AddToSourceGroup(std::string const& fileName,
|
|
cm::string_view genNameUpper);
|
|
void AddCMakeProcessToCommandLines(std::string const& infoFile,
|
|
std::string const& processName,
|
|
cmCustomCommandLines& commandLines);
|
|
void AddCleanFile(std::string const& fileName);
|
|
|
|
void ConfigFileNames(ConfigString& configString, cm::string_view prefix,
|
|
cm::string_view suffix);
|
|
void ConfigFileNamesAndGenex(ConfigString& configString, std::string& genex,
|
|
cm::string_view prefix, cm::string_view suffix);
|
|
void ConfigFileNameCommon(ConfigString& configString,
|
|
std::string const& fileName);
|
|
void ConfigFileClean(ConfigString& configString);
|
|
|
|
std::string const& GetMocBuildPath(MUFile const& muf);
|
|
|
|
bool GetQtExecutable(GenVarsT& genVars, std::string const& executable,
|
|
bool ignoreMissingTarget) const;
|
|
|
|
void handleSkipPch(cmSourceFile* sf);
|
|
void AddAutogenExecutableToDependencies(
|
|
cmQtAutoGenInitializer::GenVarsT const& genVars,
|
|
std::vector<std::string>& dependencies) const;
|
|
|
|
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 CrossConfig = false;
|
|
bool UseBetterGraph = 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 RelativeBuild;
|
|
std::string Work;
|
|
ConfigString Include;
|
|
std::string IncludeGenExp;
|
|
} Dir;
|
|
|
|
/** Autogen target variables. */
|
|
struct
|
|
{
|
|
std::string Name;
|
|
bool GlobalTarget = false;
|
|
// Settings
|
|
unsigned int Parallel = 1;
|
|
unsigned int MaxCommandLineLength =
|
|
std::numeric_limits<unsigned int>::max();
|
|
// Configuration files
|
|
std::string InfoFile;
|
|
ConfigString SettingsFile;
|
|
ConfigString ParseCacheFile;
|
|
// Dependencies
|
|
bool DependOrigin = false;
|
|
std::set<std::string> DependFiles;
|
|
std::set<cmTarget*> DependTargets;
|
|
ConfigString DepFile;
|
|
ConfigString DepFileRuleName;
|
|
// Sources to process
|
|
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
|
|
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
|
|
std::unordered_map<cmSourceFile*, MUFileHandle> ModuleUnits;
|
|
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;
|
|
ConfigString CompilationFile;
|
|
std::string CompilationFileGenex;
|
|
// 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<std::string> UiFilesNoOptions;
|
|
std::vector<UiFileT> UiFilesWithOptions;
|
|
ConfigStrings<std::vector<std::string>> Options;
|
|
std::vector<std::string> SearchPaths;
|
|
std::vector<std::pair<ConfigString /*ui header*/, std::string /*genex*/>>
|
|
UiHeaders;
|
|
} Uic;
|
|
|
|
/** rcc variables. */
|
|
struct RccT : public GenVarsT
|
|
{
|
|
RccT()
|
|
: GenVarsT(GenT::RCC)
|
|
{
|
|
}
|
|
|
|
bool GlobalTarget = false;
|
|
std::vector<Qrc> Qrcs;
|
|
} Rcc;
|
|
};
|