| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmQtAutoMocUic.h"
- #include <algorithm>
- #include <initializer_list>
- #include <list>
- #include <set>
- #include <utility>
- #include "cm_memory.hxx"
- #include "cmAlgorithms.h"
- #include "cmCryptoHash.h"
- #include "cmGeneratedFileStream.h"
- #include "cmMakefile.h"
- #include "cmQtAutoGen.h"
- #include "cmStringAlgorithms.h"
- #include "cmSystemTools.h"
- #include "cmake.h"
- #include "cmsys/FStream.hxx"
- #if defined(__APPLE__)
- # include <unistd.h>
- #endif
- static constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
- static constexpr std::size_t UiUnderscoreLength = 3; // Length of "ui_"
- cmQtAutoMocUic::IncludeKeyT::IncludeKeyT(std::string const& key,
- std::size_t basePrefixLength)
- : Key(key)
- , Dir(SubDirPrefix(key))
- , Base(cmSystemTools::GetFilenameWithoutLastExtension(key))
- {
- if (basePrefixLength != 0) {
- Base = Base.substr(basePrefixLength);
- }
- }
- void cmQtAutoMocUic::ParseCacheT::FileT::Clear()
- {
- Moc.Macro.clear();
- Moc.Include.Underscore.clear();
- Moc.Include.Dot.clear();
- Moc.Depends.clear();
- Uic.Include.clear();
- Uic.Depends.clear();
- }
- cmQtAutoMocUic::ParseCacheT::FileHandleT cmQtAutoMocUic::ParseCacheT::Get(
- std::string const& fileName) const
- {
- auto it = Map_.find(fileName);
- if (it != Map_.end()) {
- return it->second;
- }
- return FileHandleT();
- }
- cmQtAutoMocUic::ParseCacheT::GetOrInsertT
- cmQtAutoMocUic::ParseCacheT::GetOrInsert(std::string const& fileName)
- {
- // Find existing entry
- {
- auto it = Map_.find(fileName);
- if (it != Map_.end()) {
- return GetOrInsertT{ it->second, false };
- }
- }
- // Insert new entry
- return GetOrInsertT{
- Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true
- };
- }
- cmQtAutoMocUic::ParseCacheT::ParseCacheT() = default;
- cmQtAutoMocUic::ParseCacheT::~ParseCacheT() = default;
- void cmQtAutoMocUic::ParseCacheT::Clear()
- {
- Map_.clear();
- }
- bool cmQtAutoMocUic::ParseCacheT::ReadFromFile(std::string const& fileName)
- {
- cmsys::ifstream fin(fileName.c_str());
- if (!fin) {
- return false;
- }
- FileHandleT fileHandle;
- std::string line;
- while (std::getline(fin, line)) {
- // Check if this an empty or a comment line
- if (line.empty() || line.front() == '#') {
- continue;
- }
- // Drop carriage return character at the end
- if (line.back() == '\r') {
- line.pop_back();
- if (line.empty()) {
- continue;
- }
- }
- // Check if this a file name line
- if (line.front() != ' ') {
- fileHandle = GetOrInsert(line).first;
- continue;
- }
- // Bad line or bad file handle
- if (!fileHandle || (line.size() < 6)) {
- continue;
- }
- constexpr std::size_t offset = 5;
- if (cmHasLiteralPrefix(line, " mmc:")) {
- fileHandle->Moc.Macro = line.substr(offset);
- continue;
- }
- if (cmHasLiteralPrefix(line, " miu:")) {
- fileHandle->Moc.Include.Underscore.emplace_back(line.substr(offset),
- MocUnderscoreLength);
- continue;
- }
- if (cmHasLiteralPrefix(line, " mid:")) {
- fileHandle->Moc.Include.Dot.emplace_back(line.substr(offset), 0);
- continue;
- }
- if (cmHasLiteralPrefix(line, " mdp:")) {
- fileHandle->Moc.Depends.emplace_back(line.substr(offset));
- continue;
- }
- if (cmHasLiteralPrefix(line, " uic:")) {
- fileHandle->Uic.Include.emplace_back(line.substr(offset),
- UiUnderscoreLength);
- continue;
- }
- if (cmHasLiteralPrefix(line, " udp:")) {
- fileHandle->Uic.Depends.emplace_back(line.substr(offset));
- continue;
- }
- }
- return true;
- }
- bool cmQtAutoMocUic::ParseCacheT::WriteToFile(std::string const& fileName)
- {
- cmGeneratedFileStream ofs(fileName);
- if (!ofs) {
- return false;
- }
- ofs << "# Generated by CMake. Changes will be overwritten." << std::endl;
- for (auto const& pair : Map_) {
- ofs << pair.first << std::endl;
- FileT const& file = *pair.second;
- if (!file.Moc.Macro.empty()) {
- ofs << " mmc:" << file.Moc.Macro << std::endl;
- }
- for (IncludeKeyT const& item : file.Moc.Include.Underscore) {
- ofs << " miu:" << item.Key << std::endl;
- }
- for (IncludeKeyT const& item : file.Moc.Include.Dot) {
- ofs << " mid:" << item.Key << std::endl;
- }
- for (std::string const& item : file.Moc.Depends) {
- ofs << " mdp:" << item << std::endl;
- }
- for (IncludeKeyT const& item : file.Uic.Include) {
- ofs << " uic:" << item.Key << std::endl;
- }
- for (std::string const& item : file.Uic.Depends) {
- ofs << " udp:" << item << std::endl;
- }
- }
- return ofs.Close();
- }
- cmQtAutoMocUic::BaseSettingsT::BaseSettingsT() = default;
- cmQtAutoMocUic::BaseSettingsT::~BaseSettingsT() = default;
- cmQtAutoMocUic::MocSettingsT::MocSettingsT()
- {
- RegExpInclude.compile(
- "(^|\n)[ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
- }
- cmQtAutoMocUic::MocSettingsT::~MocSettingsT() = default;
- bool cmQtAutoMocUic::MocSettingsT::skipped(std::string const& fileName) const
- {
- return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
- }
- std::string cmQtAutoMocUic::MocSettingsT::MacrosString() const
- {
- std::string res;
- const auto itB = MacroFilters.cbegin();
- const auto itE = MacroFilters.cend();
- const auto itL = itE - 1;
- auto itC = itB;
- for (; itC != itE; ++itC) {
- // Separator
- if (itC != itB) {
- if (itC != itL) {
- res += ", ";
- } else {
- res += " or ";
- }
- }
- // Key
- res += itC->Key;
- }
- return res;
- }
- cmQtAutoMocUic::UicSettingsT::UicSettingsT()
- {
- RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
- }
- cmQtAutoMocUic::UicSettingsT::~UicSettingsT() = default;
- bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const
- {
- return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
- }
- void cmQtAutoMocUic::JobT::LogError(GenT genType,
- cm::string_view message) const
- {
- Gen()->AbortError();
- Gen()->Log().Error(genType, message);
- }
- void cmQtAutoMocUic::JobT::LogFileError(GenT genType, cm::string_view filename,
- cm::string_view message) const
- {
- Gen()->AbortError();
- Gen()->Log().ErrorFile(genType, filename, message);
- }
- void cmQtAutoMocUic::JobT::LogCommandError(
- GenT genType, cm::string_view message,
- std::vector<std::string> const& command, std::string const& output) const
- {
- Gen()->AbortError();
- Gen()->Log().ErrorCommand(genType, message, command, output);
- }
- bool cmQtAutoMocUic::JobT::RunProcess(GenT genType,
- cmWorkerPool::ProcessResultT& result,
- std::vector<std::string> const& command,
- std::string* infoMessage)
- {
- // Log command
- if (Log().Verbose()) {
- cm::string_view info;
- if (infoMessage != nullptr) {
- info = *infoMessage;
- }
- Log().Info(genType,
- cmStrCat(info,
- info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
- QuotedCommand(command), '\n'));
- }
- return cmWorkerPool::JobT::RunProcess(result, command,
- BaseConst().AutogenBuildDir);
- }
- void cmQtAutoMocUic::JobMocPredefsT::Process()
- {
- // (Re)generate moc_predefs.h on demand
- std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
- reason = cm::make_unique<std::string>();
- }
- if (!Update(reason.get())) {
- return;
- }
- std::string const& predefsFileRel = MocConst().PredefsFileRel;
- std::string const& predefsFileAbs = MocConst().PredefsFileAbs;
- {
- cmWorkerPool::ProcessResultT result;
- {
- // Compose command
- std::vector<std::string> cmd = MocConst().PredefsCmd;
- // Add includes
- cmAppend(cmd, MocConst().Includes);
- // Add definitions
- for (std::string const& def : MocConst().Definitions) {
- cmd.emplace_back("-D" + def);
- }
- // Execute command
- if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
- LogCommandError(GenT::MOC,
- cmStrCat("The content generation command for ",
- Quoted(predefsFileRel), " failed.\n",
- result.ErrorMessage),
- cmd, result.StdOut);
- return;
- }
- }
- // (Re)write predefs file only on demand
- if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
- if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
- LogFileError(GenT::MOC, predefsFileAbs,
- cmStrCat("Writing ", Quoted(predefsFileRel), " failed."));
- return;
- }
- } else {
- // Touch to update the time stamp
- if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
- }
- if (!cmSystemTools::Touch(predefsFileAbs, false)) {
- LogFileError(
- GenT::MOC, predefsFileAbs,
- cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."));
- return;
- }
- }
- }
- // Read file time afterwards
- if (!MocEval().PredefsTime.Load(predefsFileAbs)) {
- LogFileError(GenT::MOC, predefsFileAbs, "File time reading failed.");
- return;
- }
- }
- bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
- {
- // Test if the file exists
- if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
- ", because it doesn't exist.");
- }
- return true;
- }
- // Test if the settings changed
- if (MocConst().SettingsChanged) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
- ", because the moc settings changed.");
- }
- return true;
- }
- // Test if the executable is newer
- {
- std::string const& exec = MocConst().PredefsCmd.at(0);
- cmFileTime execTime;
- if (execTime.Load(exec)) {
- if (MocEval().PredefsTime.Older(execTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
- " because it is older than ", Quoted(exec), '.');
- }
- return true;
- }
- }
- }
- return false;
- }
- bool cmQtAutoMocUic::JobParseT::ReadFile()
- {
- // Clear old parse information
- FileHandle->ParseData->Clear();
- std::string const& fileName = FileHandle->FileName;
- // Write info
- if (Log().Verbose()) {
- Log().Info(GenT::GEN, "Parsing " + Quoted(fileName));
- }
- // Read file content
- {
- std::string error;
- if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) {
- LogFileError(GenT::GEN, fileName, "Could not read the file: " + error);
- return false;
- }
- }
- // Warn if empty
- if (Content.empty()) {
- Log().WarningFile(GenT::GEN, fileName, "The file is empty.");
- return false;
- }
- return true;
- }
- void cmQtAutoMocUic::JobParseT::CreateKeys(std::vector<IncludeKeyT>& container,
- std::set<std::string> const& source,
- std::size_t basePrefixLength)
- {
- if (source.empty()) {
- return;
- }
- container.reserve(source.size());
- for (std::string const& src : source) {
- container.emplace_back(src, basePrefixLength);
- }
- }
- void cmQtAutoMocUic::JobParseT::MocMacro()
- {
- for (KeyExpT const& filter : MocConst().MacroFilters) {
- // Run a simple find string check
- if (Content.find(filter.Key) == std::string::npos) {
- continue;
- }
- // Run the expensive regular expression check loop
- cmsys::RegularExpressionMatch match;
- if (filter.Exp.find(Content.c_str(), match)) {
- // Keep detected macro name
- FileHandle->ParseData->Moc.Macro = filter.Key;
- return;
- }
- }
- }
- void cmQtAutoMocUic::JobParseT::MocDependecies()
- {
- if (MocConst().DependFilters.empty()) {
- return;
- }
- // Find dependency strings
- std::set<std::string> parseDepends;
- for (KeyExpT const& filter : MocConst().DependFilters) {
- // Run a simple find string check
- if (Content.find(filter.Key) == std::string::npos) {
- continue;
- }
- // Run the expensive regular expression check loop
- const char* contentChars = Content.c_str();
- cmsys::RegularExpressionMatch match;
- while (filter.Exp.find(contentChars, match)) {
- {
- std::string dep = match.match(1);
- if (!dep.empty()) {
- parseDepends.emplace(std::move(dep));
- }
- }
- contentChars += match.end();
- }
- }
- // Store dependency strings
- {
- auto& Depends = FileHandle->ParseData->Moc.Depends;
- Depends.reserve(parseDepends.size());
- for (std::string const& item : parseDepends) {
- Depends.emplace_back(item);
- // Replace end of line characters in filenames
- std::string& path = Depends.back();
- std::replace(path.begin(), path.end(), '\n', ' ');
- std::replace(path.begin(), path.end(), '\r', ' ');
- }
- }
- }
- void cmQtAutoMocUic::JobParseT::MocIncludes()
- {
- if (Content.find("moc") == std::string::npos) {
- return;
- }
- std::set<std::string> underscore;
- std::set<std::string> dot;
- {
- const char* contentChars = Content.c_str();
- cmsys::RegularExpression const& regExp = MocConst().RegExpInclude;
- cmsys::RegularExpressionMatch match;
- while (regExp.find(contentChars, match)) {
- std::string incString = match.match(2);
- std::string const incBase =
- cmSystemTools::GetFilenameWithoutLastExtension(incString);
- if (cmHasLiteralPrefix(incBase, "moc_")) {
- // moc_<BASE>.cpp
- // Remove the moc_ part from the base name
- underscore.emplace(std::move(incString));
- } else {
- // <BASE>.moc
- dot.emplace(std::move(incString));
- }
- // Forward content pointer
- contentChars += match.end();
- }
- }
- auto& Include = FileHandle->ParseData->Moc.Include;
- CreateKeys(Include.Underscore, underscore, MocUnderscoreLength);
- CreateKeys(Include.Dot, dot, 0);
- }
- void cmQtAutoMocUic::JobParseT::UicIncludes()
- {
- if (Content.find("ui_") == std::string::npos) {
- return;
- }
- std::set<std::string> includes;
- {
- const char* contentChars = Content.c_str();
- cmsys::RegularExpression const& regExp = UicConst().RegExpInclude;
- cmsys::RegularExpressionMatch match;
- while (regExp.find(contentChars, match)) {
- includes.emplace(match.match(2));
- // Forward content pointer
- contentChars += match.end();
- }
- }
- CreateKeys(FileHandle->ParseData->Uic.Include, includes, UiUnderscoreLength);
- }
- void cmQtAutoMocUic::JobParseHeaderT::Process()
- {
- if (!ReadFile()) {
- return;
- }
- // Moc parsing
- if (FileHandle->Moc) {
- MocMacro();
- MocDependecies();
- }
- // Uic parsing
- if (FileHandle->Uic) {
- UicIncludes();
- }
- }
- void cmQtAutoMocUic::JobParseSourceT::Process()
- {
- if (!ReadFile()) {
- return;
- }
- // Moc parsing
- if (FileHandle->Moc) {
- MocMacro();
- MocDependecies();
- MocIncludes();
- }
- // Uic parsing
- if (FileHandle->Uic) {
- UicIncludes();
- }
- }
- void cmQtAutoMocUic::JobEvaluateT::Process()
- {
- // Evaluate for moc
- if (MocConst().Enabled) {
- // Evaluate headers
- for (auto const& pair : BaseEval().Headers) {
- if (!MocEvalHeader(pair.second)) {
- return;
- }
- }
- // Evaluate sources
- for (auto const& pair : BaseEval().Sources) {
- if (!MocEvalSource(pair.second)) {
- return;
- }
- }
- }
- // Evaluate for uic
- if (UicConst().Enabled) {
- if (!UicEval(BaseEval().Headers) || !UicEval(BaseEval().Sources)) {
- return;
- }
- }
- // Add discovered header parse jobs
- Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered);
- // Add generate job after
- Gen()->WorkerPool().EmplaceJob<JobGenerateT>();
- }
- bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source)
- {
- SourceFileT const& sourceFile = *source;
- auto const& parseData = sourceFile.ParseData->Moc;
- if (!source->Moc) {
- return true;
- }
- if (!parseData.Macro.empty()) {
- // Create a new mapping
- MappingHandleT handle = std::make_shared<MappingT>();
- handle->SourceFile = std::move(source);
- // Absolute build path
- if (BaseConst().MultiConfig) {
- handle->OutputFile = Gen()->AbsoluteIncludePath(sourceFile.BuildPath);
- } else {
- handle->OutputFile = Gen()->AbsoluteBuildPath(sourceFile.BuildPath);
- }
- // Register mapping in headers map
- MocRegisterMapping(handle, true);
- }
- return true;
- }
- bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
- SourceFileHandleT const& source)
- {
- SourceFileT const& sourceFile = *source;
- auto const& parseData = sourceFile.ParseData->Moc;
- if (!sourceFile.Moc ||
- (parseData.Macro.empty() && parseData.Include.Underscore.empty() &&
- parseData.Include.Dot.empty())) {
- return true;
- }
- std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
- std::string const sourceBase =
- cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName);
- // For relaxed mode check if the own "moc_" or ".moc" file is included
- bool const relaxedMode = MocConst().RelaxedMode;
- bool sourceIncludesMocUnderscore = false;
- bool sourceIncludesDotMoc = false;
- // Check if the sources own "moc_" or ".moc" file is included
- if (relaxedMode) {
- for (IncludeKeyT const& incKey : parseData.Include.Underscore) {
- if (incKey.Base == sourceBase) {
- sourceIncludesMocUnderscore = true;
- break;
- }
- }
- }
- for (IncludeKeyT const& incKey : parseData.Include.Dot) {
- if (incKey.Base == sourceBase) {
- sourceIncludesDotMoc = true;
- break;
- }
- }
- // Check if this source needs to be moc processed but doesn't.
- if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
- !(relaxedMode && sourceIncludesMocUnderscore)) {
- LogFileError(GenT::MOC, sourceFile.FileName,
- cmStrCat("The file contains a ", Quoted(parseData.Macro),
- " macro, but does not include ",
- Quoted(sourceBase + ".moc"),
- "!\nConsider to\n - add #include \"", sourceBase,
- ".moc\"\n - enable SKIP_AUTOMOC for this file"));
- return false;
- }
- // Evaluate "moc_" includes
- for (IncludeKeyT const& incKey : parseData.Include.Underscore) {
- std::string const headerBase = incKey.Dir + incKey.Base;
- SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
- if (!header) {
- LogFileError(GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ",
- Quoted(incKey.Key),
- ",\nbut the header could not be found "
- "in the following locations\n",
- MocMessageTestHeaders(headerBase)));
- return false;
- }
- // The include might be handled differently in relaxed mode
- if (relaxedMode && !sourceIncludesDotMoc && !parseData.Macro.empty() &&
- (incKey.Base == sourceBase)) {
- // The <BASE>.cpp file includes a Qt macro but does not include the
- // <BASE>.moc file. In this case, the moc_<BASE>.cpp should probably
- // be generated from <BASE>.cpp instead of <BASE>.h, because otherwise
- // it won't build. But warn, since this is not how it is supposed to be
- // used. This is for KDE4 compatibility.
- // Issue a warning
- Log().WarningFile(
- GenT::MOC, sourceFile.FileName,
- cmStrCat("The file contains a ", Quoted(parseData.Macro),
- " macro, but does not include ", Quoted(sourceBase + ".moc"),
- ".\nInstead it includes ", Quoted(incKey.Key),
- ".\nRunning moc on the source\n ",
- Quoted(sourceFile.FileName), "!\nBetter include ",
- Quoted(sourceBase + ".moc"),
- " for compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
- // Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
- return false;
- }
- continue;
- }
- // Check if header is skipped
- if (MocConst().skipped(header->FileName)) {
- continue;
- }
- // Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
- return false;
- }
- }
- // Evaluate ".moc" includes
- if (relaxedMode) {
- // Relaxed mode
- for (IncludeKeyT const& incKey : parseData.Include.Dot) {
- // Check if this is the sources own .moc file
- bool const ownMoc = (incKey.Base == sourceBase);
- if (ownMoc && !parseData.Macro.empty()) {
- // Create mapping for the regular use case
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
- return false;
- }
- continue;
- }
- // Try to find a header instead but issue a warning.
- // This is for KDE4 compatibility.
- std::string const headerBase = incKey.Dir + incKey.Base;
- SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
- if (!header) {
- LogFileError(
- GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
- ",\nwhich seems to be the moc file from a different source "
- "file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header"
- "could not be found in the following locations\n",
- MocMessageTestHeaders(headerBase)));
- return false;
- }
- // Check if header is skipped
- if (MocConst().skipped(header->FileName)) {
- continue;
- }
- // Issue a warning
- if (ownMoc && parseData.Macro.empty()) {
- Log().WarningFile(
- GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
- ", but does not contain a\n", MocConst().MacrosString(),
- " macro.\nRunning moc on the header\n ",
- Quoted(header->FileName), "!\nBetter include ",
- Quoted("moc_" + incKey.Base + ".cpp"),
- " for a compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
- } else {
- Log().WarningFile(
- GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
- " instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
- ".\nRunning moc on the header\n ",
- Quoted(header->FileName), "!\nBetter include ",
- Quoted("moc_" + incKey.Base + ".cpp"),
- " for compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
- }
- // Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
- return false;
- }
- }
- } else {
- // Strict mode
- for (IncludeKeyT const& incKey : parseData.Include.Dot) {
- // Check if this is the sources own .moc file
- bool const ownMoc = (incKey.Base == sourceBase);
- if (!ownMoc) {
- // Don't allow <BASE>.moc include other than own in regular mode
- LogFileError(
- GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
- ",\nwhich seems to be the moc file from a different "
- "source file.\nThis is not supported. Include ",
- Quoted(sourceBase + ".moc"),
- " to run moc on this source file."));
- return false;
- }
- // Accept but issue a warning if moc isn't required
- if (parseData.Macro.empty()) {
- Log().WarningFile(GenT::MOC, sourceFile.FileName,
- cmStrCat("The file includes the moc file ",
- Quoted(incKey.Key),
- ", but does not contain a ",
- MocConst().MacrosString(), " macro."));
- }
- // Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
- return false;
- }
- }
- }
- return true;
- }
- cmQtAutoMocUic::SourceFileHandleT
- cmQtAutoMocUic::JobEvaluateT::MocFindIncludedHeader(
- std::string const& includerDir, std::string const& includeBase) const
- {
- // Search in vicinity of the source
- {
- SourceFileHandleT res = MocFindHeader(includerDir + includeBase);
- if (res) {
- return res;
- }
- }
- // Search in include directories
- for (std::string const& path : MocConst().IncludePaths) {
- std::string testPath = cmStrCat(path, '/', includeBase);
- SourceFileHandleT res = MocFindHeader(testPath);
- if (res) {
- return res;
- }
- }
- // Return without success
- return SourceFileHandleT();
- }
- cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader(
- std::string const& basePath) const
- {
- std::string testPath;
- testPath.reserve(basePath.size() + 8);
- for (std::string const& ext : BaseConst().HeaderExtensions) {
- testPath.clear();
- testPath += basePath;
- testPath += '.';
- testPath += ext;
- cmFileTime fileTime;
- if (fileTime.Load(testPath)) {
- // Compute real path of the file
- testPath = cmSystemTools::GetRealPath(testPath);
- // Return a known file if it exists already
- {
- auto it = BaseEval().Headers.find(testPath);
- if (it != BaseEval().Headers.end()) {
- return it->second;
- }
- }
- // Created and return discovered file entry
- SourceFileHandleT& res = MocEval().HeadersDiscovered[testPath];
- if (!res) {
- res = std::make_shared<SourceFileT>(testPath);
- res->FileTime = fileTime;
- res->Moc = true;
- }
- return res;
- }
- }
- // Return without success
- return SourceFileHandleT();
- }
- std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders(
- cm::string_view fileBase) const
- {
- std::string const exts =
- cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}');
- // Compose result string
- std::string res = cmStrCat(" ", fileBase, exts, '\n');
- for (std::string const& path : MocConst().IncludePaths) {
- res += cmStrCat(" ", path, '/', fileBase, exts, '\n');
- }
- return res;
- }
- bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
- std::string const& includeString, SourceFileHandleT includerFileHandle,
- SourceFileHandleT sourceFileHandle, bool sourceIsHeader) const
- {
- // Check if this file is already included
- MappingHandleT& handle = MocEval().Includes[includeString];
- if (handle) {
- // Check if the output file would be generated from different source files
- if (handle->SourceFile != sourceFileHandle) {
- std::string files =
- cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
- for (auto const& item : handle->IncluderFiles) {
- files += cmStrCat(" ", Quoted(item->FileName), '\n');
- }
- LogError(
- GenT::MOC,
- cmStrCat("The source files\n", files,
- "contain the same include string ", Quoted(includeString),
- ", but\nthe moc file would be generated from different "
- "source files\n ",
- Quoted(sourceFileHandle->FileName), " and\n ",
- Quoted(handle->SourceFile->FileName),
- ".\nConsider to\n"
- " - not include the \"moc_<NAME>.cpp\" file\n"
- " - add a directory prefix to a \"<NAME>.moc\" include "
- "(e.g \"sub/<NAME>.moc\")\n"
- " - rename the source file(s)\n"));
- return false;
- }
- // The same mapping already exists. Just add to the includers list.
- handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- return true;
- }
- // Create a new mapping
- handle = std::make_shared<MappingT>();
- handle->IncludeString = includeString;
- handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- handle->SourceFile = std::move(sourceFileHandle);
- handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
- // Register mapping in sources/headers map
- MocRegisterMapping(handle, sourceIsHeader);
- return true;
- }
- void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping(
- MappingHandleT mappingHandle, bool sourceIsHeader) const
- {
- auto& regMap =
- sourceIsHeader ? MocEval().HeaderMappings : MocEval().SourceMappings;
- // Check if source file already gets mapped
- auto& regHandle = regMap[mappingHandle->SourceFile->FileName];
- if (!regHandle) {
- // Yet unknown mapping
- regHandle = std::move(mappingHandle);
- } else {
- // Mappings with include string override those without
- if (!mappingHandle->IncludeString.empty()) {
- regHandle = std::move(mappingHandle);
- }
- }
- }
- bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap)
- {
- for (auto const& pair : fileMap) {
- if (!UicEvalFile(pair.second)) {
- return false;
- }
- }
- return true;
- }
- bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
- SourceFileHandleT const& sourceFileHandle)
- {
- SourceFileT const& sourceFile = *sourceFileHandle;
- auto const& Include = sourceFile.ParseData->Uic.Include;
- if (!sourceFile.Uic || Include.empty()) {
- return true;
- }
- std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
- for (IncludeKeyT const& incKey : Include) {
- // Find .ui file name
- SourceFileHandleT uiFileHandle =
- UicFindIncludedUi(sourceFile.FileName, sourceDir, incKey);
- if (!uiFileHandle || UicConst().skipped(uiFileHandle->FileName)) {
- continue;
- }
- // Register mapping
- if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle),
- sourceFileHandle)) {
- return false;
- }
- }
- return true;
- }
- bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
- std::string const& includeString, SourceFileHandleT uiFileHandle,
- SourceFileHandleT includerFileHandle)
- {
- auto& Includes = Gen()->UicEval().Includes;
- auto it = Includes.find(includeString);
- if (it != Includes.end()) {
- MappingHandleT const& handle = it->second;
- if (handle->SourceFile != uiFileHandle) {
- // The output file already gets generated - from a different .ui file!
- std::string files =
- cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n');
- for (auto const& item : handle->IncluderFiles) {
- files += cmStrCat(" ", Quoted(item->FileName), '\n');
- }
- LogError(
- GenT::UIC,
- cmStrCat(
- "The source files\n", files, "contain the same include string ",
- Quoted(includeString),
- ", but\nthe uic file would be generated from different "
- "user interface files\n ",
- Quoted(uiFileHandle->FileName), " and\n ",
- Quoted(handle->SourceFile->FileName),
- ".\nConsider to\n"
- " - add a directory prefix to a \"ui_<NAME>.h\" include "
- "(e.g \"sub/ui_<NAME>.h\")\n"
- " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
- "include(s)\n"));
- return false;
- }
- // Add includer file to existing mapping
- handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- } else {
- // New mapping handle
- MappingHandleT handle = std::make_shared<MappingT>();
- handle->IncludeString = includeString;
- handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- handle->SourceFile = std::move(uiFileHandle);
- handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
- // Register mapping
- Includes.emplace(includeString, std::move(handle));
- }
- return true;
- }
- cmQtAutoMocUic::SourceFileHandleT
- cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi(
- std::string const& sourceFile, std::string const& sourceDir,
- IncludeKeyT const& incKey) const
- {
- std::string searchFileName = cmStrCat(incKey.Base, ".ui");
- // Collect search paths list
- std::vector<std::string> testFiles;
- {
- auto& searchPaths = UicConst().SearchPaths;
- testFiles.reserve((searchPaths.size() + 1) * 2);
- // Vicinity of the source
- testFiles.emplace_back(sourceDir + searchFileName);
- if (!incKey.Dir.empty()) {
- testFiles.emplace_back(cmStrCat(sourceDir, incKey.Dir, searchFileName));
- }
- // AUTOUIC search paths
- if (!searchPaths.empty()) {
- for (std::string const& sPath : searchPaths) {
- testFiles.emplace_back(cmStrCat(sPath, '/', searchFileName));
- }
- if (!incKey.Dir.empty()) {
- for (std::string const& sPath : searchPaths) {
- testFiles.emplace_back(
- cmStrCat(sPath, '/', incKey.Dir, searchFileName));
- }
- }
- }
- }
- // Search for the .ui file!
- for (std::string const& testFile : testFiles) {
- cmFileTime fileTime;
- if (fileTime.Load(testFile)) {
- // .ui file found in files system!
- std::string realPath = cmSystemTools::GetRealPath(testFile);
- // Get or create .ui file handle
- SourceFileHandleT& handle = Gen()->UicEval().UiFiles[realPath];
- if (!handle) {
- // The file wasn't registered, yet
- handle = std::make_shared<SourceFileT>(realPath);
- handle->FileTime = fileTime;
- }
- return handle;
- }
- }
- // Log error
- {
- std::string files;
- for (std::string const& testFile : testFiles) {
- files += cmStrCat(" ", Quoted(testFile), '\n');
- }
- LogFileError(
- GenT::UIC, sourceFile,
- cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
- ",\nbut the user interface file ", Quoted(searchFileName),
- "\ncould not be found in the following locations\n", files));
- }
- return SourceFileHandleT();
- }
- void cmQtAutoMocUic::JobGenerateT::Process()
- {
- // Add moc compile jobs
- if (MocConst().Enabled) {
- for (auto const& pair : MocEval().HeaderMappings) {
- // Register if this mapping is a candidate for mocs_compilation.cpp
- bool const compFile = pair.second->IncludeString.empty();
- if (compFile) {
- MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath);
- }
- if (!MocGenerate(pair.second, compFile)) {
- return;
- }
- }
- for (auto const& pair : MocEval().SourceMappings) {
- if (!MocGenerate(pair.second, false)) {
- return;
- }
- }
- // Add mocs compilations job on demand
- Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
- }
- // Add uic compile jobs
- if (UicConst().Enabled) {
- for (auto const& pair : Gen()->UicEval().Includes) {
- if (!UicGenerate(pair.second)) {
- return;
- }
- }
- }
- // Add finish job
- Gen()->WorkerPool().EmplaceJob<JobFinishT>();
- }
- bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping,
- bool compFile) const
- {
- std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
- reason = cm::make_unique<std::string>();
- }
- if (MocUpdate(*mapping, reason.get())) {
- // Create the parent directory
- if (!MakeParentDirectory(mapping->OutputFile)) {
- LogFileError(GenT::MOC, mapping->OutputFile,
- "Could not create parent directory.");
- return false;
- }
- // Add moc job
- Gen()->WorkerPool().EmplaceJob<JobMocT>(mapping, std::move(reason));
- // Check if a moc job for a mocs_compilation.cpp entry was generated
- if (compFile) {
- MocEval().CompUpdated = true;
- }
- }
- return true;
- }
- bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
- std::string* reason) const
- {
- std::string const& sourceFile = mapping.SourceFile->FileName;
- std::string const& outputFile = mapping.OutputFile;
- // Test if the output file exists
- cmFileTime outputFileTime;
- if (!outputFileTime.Load(outputFile)) {
- if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", Quoted(outputFile),
- ", because it doesn't exist, from ", Quoted(sourceFile));
- }
- return true;
- }
- // Test if any setting changed
- if (MocConst().SettingsChanged) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- ", because the uic settings changed, from ",
- Quoted(sourceFile));
- }
- return true;
- }
- // Test if the source file is newer
- if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- ", because it's older than its source file, from ",
- Quoted(sourceFile));
- }
- return true;
- }
- // Test if the moc_predefs file is newer
- if (!MocConst().PredefsFileAbs.empty()) {
- if (outputFileTime.Older(MocEval().PredefsTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat(
- "Generating ", Quoted(outputFile), ", because it's older than ",
- Quoted(MocConst().PredefsFileAbs), ", from ", Quoted(sourceFile));
- }
- return true;
- }
- }
- // Test if the moc executable is newer
- if (outputFileTime.Older(MocConst().ExecutableTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- ", because it's older than the moc executable, from ",
- Quoted(sourceFile));
- }
- return true;
- }
- // Test if a dependency file is newer
- {
- // Check dependency timestamps
- std::string const sourceDir = SubDirPrefix(sourceFile);
- for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) {
- // Find dependency file
- auto const depMatch = MocFindDependency(sourceDir, dep);
- if (depMatch.first.empty()) {
- Log().WarningFile(GenT::MOC, sourceFile,
- "Could not find dependency file " + Quoted(dep));
- continue;
- }
- // Test if dependency file is older
- if (outputFileTime.Older(depMatch.second)) {
- if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", Quoted(outputFile),
- ", because it's older than its dependency file ",
- Quoted(depMatch.first), ", from ", Quoted(sourceFile));
- }
- return true;
- }
- }
- }
- return false;
- }
- std::pair<std::string, cmFileTime>
- cmQtAutoMocUic::JobGenerateT::MocFindDependency(
- std::string const& sourceDir, std::string const& includeString) const
- {
- using ResPair = std::pair<std::string, cmFileTime>;
- // Search in vicinity of the source
- {
- ResPair res{ sourceDir + includeString, {} };
- if (res.second.Load(res.first)) {
- return res;
- }
- }
- // Search in include directories
- for (std::string const& includePath : MocConst().IncludePaths) {
- ResPair res{ cmStrCat(includePath, '/', includeString), {} };
- if (res.second.Load(res.first)) {
- return res;
- }
- }
- // Return empty
- return ResPair();
- }
- bool cmQtAutoMocUic::JobGenerateT::UicGenerate(
- MappingHandleT const& mapping) const
- {
- std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
- reason = cm::make_unique<std::string>();
- }
- if (UicUpdate(*mapping, reason.get())) {
- // Create the parent directory
- if (!MakeParentDirectory(mapping->OutputFile)) {
- LogFileError(GenT::UIC, mapping->OutputFile,
- "Could not create parent directory.");
- return false;
- }
- // Add uic job
- Gen()->WorkerPool().EmplaceJob<JobUicT>(mapping, std::move(reason));
- }
- return true;
- }
- bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
- std::string* reason) const
- {
- std::string const& sourceFile = mapping.SourceFile->FileName;
- std::string const& outputFile = mapping.OutputFile;
- // Test if the build file exists
- cmFileTime outputFileTime;
- if (!outputFileTime.Load(outputFile)) {
- if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", Quoted(outputFile),
- ", because it doesn't exist, from ", Quoted(sourceFile));
- }
- return true;
- }
- // Test if the uic settings changed
- if (UicConst().SettingsChanged) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- ", because the uic settings changed, from ",
- Quoted(sourceFile));
- }
- return true;
- }
- // Test if the source file is newer
- if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- " because it's older than the source file ",
- Quoted(sourceFile));
- }
- return true;
- }
- // Test if the uic executable is newer
- if (outputFileTime.Older(UicConst().ExecutableTime)) {
- if (reason != nullptr) {
- *reason = cmStrCat("Generating ", Quoted(outputFile),
- ", because it's older than the uic executable, from ",
- Quoted(sourceFile));
- }
- return true;
- }
- return false;
- }
- void cmQtAutoMocUic::JobMocT::Process()
- {
- std::string const& sourceFile = Mapping->SourceFile->FileName;
- std::string const& outputFile = Mapping->OutputFile;
- // Compose moc command
- std::vector<std::string> cmd;
- cmd.push_back(MocConst().Executable);
- // Add options
- cmAppend(cmd, MocConst().AllOptions);
- // Add predefs include
- if (!MocConst().PredefsFileAbs.empty()) {
- cmd.emplace_back("--include");
- cmd.push_back(MocConst().PredefsFileAbs);
- }
- cmd.emplace_back("-o");
- cmd.push_back(outputFile);
- cmd.push_back(sourceFile);
- // Execute moc command
- cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
- // Moc command success. Print moc output.
- if (!result.StdOut.empty()) {
- Log().Info(GenT::MOC, result.StdOut);
- }
- } else {
- // Moc command failed
- std::string includers;
- if (!Mapping->IncluderFiles.empty()) {
- includers = "included by\n";
- for (auto const& item : Mapping->IncluderFiles) {
- includers += cmStrCat(" ", Quoted(item->FileName), '\n');
- }
- }
- LogCommandError(GenT::MOC,
- cmStrCat("The moc process failed to compile\n ",
- Quoted(sourceFile), "\ninto\n ",
- Quoted(outputFile), '\n', includers,
- result.ErrorMessage),
- cmd, result.StdOut);
- }
- }
- void cmQtAutoMocUic::JobUicT::Process()
- {
- std::string const& sourceFile = Mapping->SourceFile->FileName;
- std::string const& outputFile = Mapping->OutputFile;
- // Compose uic command
- std::vector<std::string> cmd;
- cmd.push_back(UicConst().Executable);
- {
- std::vector<std::string> allOpts = UicConst().TargetOptions;
- auto optionIt = UicConst().Options.find(sourceFile);
- if (optionIt != UicConst().Options.end()) {
- UicMergeOptions(allOpts, optionIt->second,
- (BaseConst().QtVersionMajor == 5));
- }
- cmAppend(cmd, allOpts);
- }
- cmd.emplace_back("-o");
- cmd.emplace_back(outputFile);
- cmd.emplace_back(sourceFile);
- cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::UIC, result, cmd, Reason.get())) {
- // Uic command success
- // Print uic output
- if (!result.StdOut.empty()) {
- Log().Info(GenT::UIC, result.StdOut);
- }
- } else {
- // Uic command failed
- std::string includers;
- for (auto const& item : Mapping->IncluderFiles) {
- includers += cmStrCat(" ", Quoted(item->FileName), '\n');
- }
- LogCommandError(GenT::UIC,
- cmStrCat("The uic process failed to compile\n ",
- Quoted(sourceFile), "\ninto\n ",
- Quoted(outputFile), "\nincluded by\n", includers,
- result.ErrorMessage),
- cmd, result.StdOut);
- }
- }
- void cmQtAutoMocUic::JobMocsCompilationT::Process()
- {
- // Compose mocs compilation file content
- std::string content =
- "// This file is autogenerated. Changes will be overwritten.\n";
- if (MocEval().CompFiles.empty()) {
- // Placeholder content
- content += "// No files found that require moc or the moc files are "
- "included\n"
- "enum some_compilers { need_more_than_nothing };\n";
- } else {
- // Valid content
- const bool mc = BaseConst().MultiConfig;
- cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
- cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
- content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
- }
- std::string const& compAbs = MocConst().CompFileAbs;
- if (cmQtAutoGenerator::FileDiffers(compAbs, content)) {
- // Actually write mocs compilation file
- if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Generating MOC compilation " + compAbs);
- }
- if (!FileWrite(compAbs, content)) {
- LogFileError(GenT::MOC, compAbs,
- "mocs compilation file writing failed.");
- }
- } else if (MocEval().CompUpdated) {
- // Only touch mocs compilation file
- if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Touching mocs compilation " + compAbs);
- }
- if (!cmSystemTools::Touch(compAbs, false)) {
- LogFileError(GenT::MOC, compAbs,
- "mocs compilation file touching failed.");
- }
- }
- }
- void cmQtAutoMocUic::JobFinishT::Process()
- {
- Gen()->AbortSuccess();
- }
- cmQtAutoMocUic::cmQtAutoMocUic() = default;
- cmQtAutoMocUic::~cmQtAutoMocUic() = default;
- bool cmQtAutoMocUic::Init(cmMakefile* makefile)
- {
- // Utility lambdas
- auto InfoGet = [makefile](cm::string_view key) {
- return makefile->GetSafeDefinition(std::string(key));
- };
- auto InfoGetBool = [makefile](cm::string_view key) {
- return makefile->IsOn(std::string(key));
- };
- auto InfoGetList =
- [makefile](cm::string_view key) -> std::vector<std::string> {
- return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
- };
- auto InfoGetLists =
- [makefile](cm::string_view key) -> std::vector<std::vector<std::string>> {
- std::vector<std::vector<std::string>> lists;
- {
- std::string const value = makefile->GetSafeDefinition(std::string(key));
- std::string::size_type pos = 0;
- while (pos < value.size()) {
- std::string::size_type next = value.find(ListSep, pos);
- std::string::size_type length =
- (next != std::string::npos) ? next - pos : value.size() - pos;
- // Remove enclosing braces
- if (length >= 2) {
- std::string::const_iterator itBeg = value.begin() + (pos + 1);
- std::string::const_iterator itEnd = itBeg + (length - 2);
- lists.emplace_back(cmExpandedList(std::string(itBeg, itEnd)));
- }
- pos += length;
- pos += ListSep.size();
- }
- }
- return lists;
- };
- auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
- if (const char* valueConf =
- makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
- return std::string(valueConf);
- }
- return makefile->GetSafeDefinition(std::string(key));
- };
- auto InfoGetConfigList =
- [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
- return cmExpandedList(InfoGetConfig(key));
- };
- auto LogInfoError = [this](cm::string_view msg) -> bool {
- this->Log().Error(GenT::GEN,
- cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
- return false;
- };
- auto MatchSizes = [&LogInfoError](cm::string_view keyA, cm::string_view keyB,
- std::size_t sizeA,
- std::size_t sizeB) -> bool {
- if (sizeA == sizeB) {
- return true;
- }
- return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA,
- ") ", keyB, '(', sizeB, ')'));
- };
- // -- Read info file
- if (!makefile->ReadListFile(InfoFile())) {
- return LogInfoError("File processing failed");
- }
- // -- Meta
- Logger_.RaiseVerbosity(InfoGet("AM_VERBOSITY"));
- BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
- {
- unsigned long num = 1;
- if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) {
- num = std::max<unsigned long>(num, 1);
- num = std::min<unsigned long>(num, ParallelMax);
- }
- WorkerPool_.SetThreadCount(static_cast<unsigned int>(num));
- }
- BaseConst_.HeaderExtensions =
- makefile->GetCMakeInstance()->GetHeaderExtensions();
- // - Files and directories
- BaseConst_.IncludeProjectDirsBefore =
- InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
- BaseConst_.ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR");
- BaseConst_.ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR");
- BaseConst_.CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
- BaseConst_.CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
- BaseConst_.AutogenBuildDir = InfoGet("AM_BUILD_DIR");
- if (BaseConst_.AutogenBuildDir.empty()) {
- return LogInfoError("Autogen build directory missing.");
- }
- BaseConst_.AutogenIncludeDir = InfoGetConfig("AM_INCLUDE_DIR");
- if (BaseConst_.AutogenIncludeDir.empty()) {
- return LogInfoError("Autogen include directory missing.");
- }
- BaseConst_.CMakeExecutable = InfoGetConfig("AM_CMAKE_EXECUTABLE");
- if (BaseConst_.CMakeExecutable.empty()) {
- return LogInfoError("CMake executable file name missing.");
- }
- if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
- return LogInfoError(cmStrCat("The CMake executable ",
- Quoted(BaseConst_.CMakeExecutable),
- " does not exist."));
- }
- BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
- if (BaseConst_.ParseCacheFile.empty()) {
- return LogInfoError("Parse cache file name missing.");
- }
- // - Settings file
- SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE");
- if (SettingsFile_.empty()) {
- return LogInfoError("Settings file name missing.");
- }
- // - Qt environment
- {
- unsigned long qtv = BaseConst_.QtVersionMajor;
- if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) {
- BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
- }
- }
- // - Moc
- MocConst_.Executable = InfoGet("AM_QT_MOC_EXECUTABLE");
- if (!MocConst().Executable.empty()) {
- MocConst_.Enabled = true;
- // Load the executable file time
- if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
- return LogInfoError(cmStrCat("The moc executable ",
- Quoted(MocConst_.Executable),
- " does not exist."));
- }
- for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
- MocConst_.SkipList.insert(std::move(sfl));
- }
- MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
- MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
- MocConst_.Options = InfoGetList("AM_MOC_OPTIONS");
- MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
- for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) {
- MocConst_.MacroFilters.emplace_back(
- item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
- }
- {
- auto addFilter = [this, &LogInfoError](std::string const& key,
- std::string const& exp) -> bool {
- auto filterErr = [&LogInfoError, &key,
- &exp](cm::string_view err) -> bool {
- return LogInfoError(cmStrCat("AUTOMOC_DEPEND_FILTERS: ", err, '\n',
- " Key: ", Quoted(key), '\n',
- " Exp: ", Quoted(exp), '\n'));
- };
- if (key.empty()) {
- return filterErr("Key is empty");
- }
- if (exp.empty()) {
- return filterErr("Regular expression is empty");
- }
- this->MocConst_.DependFilters.emplace_back(key, exp);
- if (!this->MocConst_.DependFilters.back().Exp.is_valid()) {
- return filterErr("Regular expression compiling failed");
- }
- return true;
- };
- // Insert default filter for Q_PLUGIN_METADATA
- if (BaseConst().QtVersionMajor != 4) {
- if (!addFilter("Q_PLUGIN_METADATA",
- "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
- "[^\\)]*FILE[ \t]*\"([^\"]+)\"")) {
- return false;
- }
- }
- // Insert user defined dependency filters
- std::vector<std::string> flts = InfoGetList("AM_MOC_DEPEND_FILTERS");
- if ((flts.size() % 2) != 0) {
- return LogInfoError(
- "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
- }
- for (auto itC = flts.begin(), itE = flts.end(); itC != itE; itC += 2) {
- if (!addFilter(*itC, *(itC + 1))) {
- return false;
- }
- }
- }
- MocConst_.PredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
- }
- // - Uic
- UicConst_.Executable = InfoGet("AM_QT_UIC_EXECUTABLE");
- if (!UicConst().Executable.empty()) {
- UicConst_.Enabled = true;
- // Load the executable file time
- if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
- return LogInfoError(cmStrCat("The uic executable ",
- Quoted(UicConst_.Executable),
- " does not exist."));
- }
- for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
- UicConst_.SkipList.insert(std::move(sfl));
- }
- UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
- UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
- {
- cm::string_view const keyFiles = "AM_UIC_OPTIONS_FILES";
- cm::string_view const keyOpts = "AM_UIC_OPTIONS_OPTIONS";
- auto sources = InfoGetList(keyFiles);
- auto options = InfoGetLists(keyOpts);
- if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) {
- return false;
- }
- auto fitEnd = sources.cend();
- auto fit = sources.begin();
- auto oit = options.begin();
- while (fit != fitEnd) {
- UicConst_.Options[*fit] = std::move(*oit);
- ++fit;
- ++oit;
- }
- }
- }
- // - Headers and sources
- {
- auto makeSource =
- [&LogInfoError](std::string const& fileName,
- std::string const& fileFlags) -> SourceFileHandleT {
- if (fileFlags.size() != 2) {
- LogInfoError("Invalid file flags string size");
- return SourceFileHandleT();
- }
- cmFileTime fileTime;
- if (!fileTime.Load(fileName)) {
- LogInfoError("The source file " + cmQtAutoGen::Quoted(fileName) +
- " does not exist.");
- return SourceFileHandleT();
- }
- SourceFileHandleT sfh = std::make_shared<SourceFileT>(fileName);
- sfh->FileTime = fileTime;
- sfh->Moc = (fileFlags[0] == 'M');
- sfh->Uic = (fileFlags[1] == 'U');
- return sfh;
- };
- // Headers
- {
- // Get file lists
- cm::string_view const keyFiles = "AM_HEADERS";
- cm::string_view const keyFlags = "AM_HEADERS_FLAGS";
- std::vector<std::string> files = InfoGetList(keyFiles);
- std::vector<std::string> flags = InfoGetList(keyFlags);
- std::vector<std::string> builds;
- if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
- return false;
- }
- if (MocConst().Enabled) {
- cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS";
- builds = InfoGetList(keyPaths);
- if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
- return false;
- }
- }
- // Process file lists
- for (std::size_t ii = 0; ii != files.size(); ++ii) {
- std::string& fileName(files[ii]);
- SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
- if (!sfh) {
- return false;
- }
- if (MocConst().Enabled) {
- sfh->BuildPath = std::move(builds[ii]);
- if (sfh->BuildPath.empty()) {
- Log().ErrorFile(GenT::GEN, this->InfoFile(),
- "Header file build path is empty");
- return false;
- }
- }
- BaseEval().Headers.emplace(std::move(fileName), std::move(sfh));
- }
- }
- // Sources
- {
- cm::string_view const keyFiles = "AM_SOURCES";
- cm::string_view const keyFlags = "AM_SOURCES_FLAGS";
- std::vector<std::string> files = InfoGetList(keyFiles);
- std::vector<std::string> flags = InfoGetList(keyFlags);
- if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
- return false;
- }
- // Process file lists
- for (std::size_t ii = 0; ii != files.size(); ++ii) {
- std::string& fileName(files[ii]);
- SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
- if (!sfh) {
- return false;
- }
- BaseEval().Sources.emplace(std::move(fileName), std::move(sfh));
- }
- }
- }
- // Init derived information
- // ------------------------
- // Moc variables
- if (MocConst().Enabled) {
- // Mocs compilation file
- MocConst_.CompFileAbs = AbsoluteBuildPath("mocs_compilation.cpp");
- // Moc predefs file
- if (!MocConst_.PredefsCmd.empty()) {
- if (BaseConst_.MultiConfig) {
- MocConst_.PredefsFileRel =
- cmStrCat("moc_predefs_", InfoConfig(), ".h");
- } else {
- MocConst_.PredefsFileRel = "moc_predefs.h";
- }
- MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel);
- }
- // Sort include directories on demand
- if (BaseConst().IncludeProjectDirsBefore) {
- // Move strings to temporary list
- std::list<std::string> includes(MocConst().IncludePaths.begin(),
- MocConst().IncludePaths.end());
- MocConst_.IncludePaths.clear();
- MocConst_.IncludePaths.reserve(includes.size());
- // Append project directories only
- {
- std::initializer_list<cm::string_view> const movePaths = {
- BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir
- };
- for (cm::string_view const& ppath : movePaths) {
- std::list<std::string>::iterator it = includes.begin();
- while (it != includes.end()) {
- std::string const& path = *it;
- if (cmHasPrefix(path, ppath)) {
- MocConst_.IncludePaths.push_back(path);
- it = includes.erase(it);
- } else {
- ++it;
- }
- }
- }
- }
- // Append remaining directories
- MocConst_.IncludePaths.insert(MocConst_.IncludePaths.end(),
- includes.begin(), includes.end());
- }
- // Compose moc includes list
- {
- std::set<std::string> frameworkPaths;
- for (std::string const& path : MocConst().IncludePaths) {
- MocConst_.Includes.push_back("-I" + path);
- // Extract framework path
- if (cmHasLiteralSuffix(path, ".framework/Headers")) {
- // Go up twice to get to the framework root
- std::vector<std::string> pathComponents;
- cmSystemTools::SplitPath(path, pathComponents);
- frameworkPaths.emplace(cmSystemTools::JoinPath(
- pathComponents.begin(), pathComponents.end() - 2));
- }
- }
- // Append framework includes
- for (std::string const& path : frameworkPaths) {
- MocConst_.Includes.emplace_back("-F");
- MocConst_.Includes.push_back(path);
- }
- }
- // Setup single list with all options
- {
- // Add includes
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Includes.begin(),
- MocConst().Includes.end());
- // Add definitions
- for (std::string const& def : MocConst().Definitions) {
- MocConst_.AllOptions.push_back("-D" + def);
- }
- // Add options
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Options.begin(),
- MocConst().Options.end());
- }
- }
- return true;
- }
- template <class JOBTYPE>
- void cmQtAutoMocUic::CreateParseJobs(SourceFileMapT const& sourceMap)
- {
- cmFileTime const parseCacheTime = BaseEval().ParseCacheTime;
- ParseCacheT& parseCache = BaseEval().ParseCache;
- for (auto& src : sourceMap) {
- // Get or create the file parse data reference
- ParseCacheT::GetOrInsertT cacheEntry = parseCache.GetOrInsert(src.first);
- src.second->ParseData = std::move(cacheEntry.first);
- // Create a parse job if the cache file was missing or is older
- if (cacheEntry.second || src.second->FileTime.Newer(parseCacheTime)) {
- BaseEval().ParseCacheChanged = true;
- WorkerPool().EmplaceJob<JOBTYPE>(src.second);
- }
- }
- }
- void cmQtAutoMocUic::InitJobs()
- {
- // Add moc_predefs.h job
- if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) {
- WorkerPool().EmplaceJob<JobMocPredefsT>();
- }
- // Add header parse jobs
- CreateParseJobs<JobParseHeaderT>(BaseEval().Headers);
- // Add source parse jobs
- CreateParseJobs<JobParseSourceT>(BaseEval().Sources);
- // Add evaluate job
- WorkerPool().EmplaceJob<JobEvaluateT>();
- }
- bool cmQtAutoMocUic::Process()
- {
- SettingsFileRead();
- ParseCacheRead();
- if (!CreateDirectories()) {
- return false;
- }
- InitJobs();
- if (!WorkerPool_.Process(this)) {
- return false;
- }
- if (JobError_) {
- return false;
- }
- if (!ParseCacheWrite()) {
- return false;
- }
- if (!SettingsFileWrite()) {
- return false;
- }
- return true;
- }
- void cmQtAutoMocUic::SettingsFileRead()
- {
- // Compose current settings strings
- {
- cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
- auto cha = [&cryptoHash](cm::string_view value) {
- cryptoHash.Append(value);
- cryptoHash.Append(";");
- };
- if (MocConst_.Enabled) {
- cryptoHash.Initialize();
- cha(MocConst().Executable);
- std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(),
- cha);
- cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE");
- std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(),
- cha);
- for (auto const& filter : MocConst().DependFilters) {
- cha(filter.Key);
- }
- for (auto const& filter : MocConst().MacroFilters) {
- cha(filter.Key);
- }
- SettingsStringMoc_ = cryptoHash.FinalizeHex();
- }
- if (UicConst().Enabled) {
- cryptoHash.Initialize();
- cha(UicConst().Executable);
- std::for_each(UicConst().TargetOptions.begin(),
- UicConst().TargetOptions.end(), cha);
- for (const auto& item : UicConst().Options) {
- cha(item.first);
- std::for_each(item.second.begin(), item.second.end(), cha);
- }
- SettingsStringUic_ = cryptoHash.FinalizeHex();
- }
- }
- // Read old settings and compare
- {
- std::string content;
- if (cmQtAutoGenerator::FileRead(content, SettingsFile_)) {
- if (MocConst().Enabled) {
- if (SettingsStringMoc_ != SettingsFind(content, "moc")) {
- MocConst_.SettingsChanged = true;
- }
- }
- if (UicConst().Enabled) {
- if (SettingsStringUic_ != SettingsFind(content, "uic")) {
- UicConst_.SettingsChanged = true;
- }
- }
- // In case any setting changed remove the old settings file.
- // This triggers a full rebuild on the next run if the current
- // build is aborted before writing the current settings in the end.
- if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
- cmSystemTools::RemoveFile(SettingsFile_);
- }
- } else {
- // Settings file read failed
- if (MocConst().Enabled) {
- MocConst_.SettingsChanged = true;
- }
- if (UicConst().Enabled) {
- UicConst_.SettingsChanged = true;
- }
- }
- }
- }
- bool cmQtAutoMocUic::SettingsFileWrite()
- {
- // Only write if any setting changed
- if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
- if (Log().Verbose()) {
- Log().Info(GenT::GEN, "Writing settings file " + Quoted(SettingsFile_));
- }
- // Compose settings file content
- std::string content;
- {
- auto SettingAppend = [&content](cm::string_view key,
- cm::string_view value) {
- if (!value.empty()) {
- content += cmStrCat(key, ':', value, '\n');
- }
- };
- SettingAppend("moc", SettingsStringMoc_);
- SettingAppend("uic", SettingsStringUic_);
- }
- // Write settings file
- std::string error;
- if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) {
- Log().ErrorFile(GenT::GEN, SettingsFile_,
- "Settings file writing failed. " + error);
- // Remove old settings file to trigger a full rebuild on the next run
- cmSystemTools::RemoveFile(SettingsFile_);
- return false;
- }
- }
- return true;
- }
- void cmQtAutoMocUic::ParseCacheRead()
- {
- cm::string_view reason;
- // Don't read the cache if it is invalid
- if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
- reason = "Refreshing parse cache because it doesn't exist.";
- } else if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
- reason = "Refreshing parse cache because the settings changed.";
- } else if (BaseEval().ParseCacheTime.Older(
- BaseConst().CMakeExecutableTime)) {
- reason =
- "Refreshing parse cache because it is older than the CMake executable.";
- }
- if (!reason.empty()) {
- // Don't read but refresh the complete parse cache
- if (Log().Verbose()) {
- Log().Info(GenT::GEN, reason);
- }
- BaseEval().ParseCacheChanged = true;
- } else {
- // Read parse cache
- BaseEval().ParseCache.ReadFromFile(BaseConst().ParseCacheFile);
- }
- }
- bool cmQtAutoMocUic::ParseCacheWrite()
- {
- if (BaseEval().ParseCacheChanged) {
- if (Log().Verbose()) {
- Log().Info(GenT::GEN,
- "Writing parse cache file " +
- Quoted(BaseConst().ParseCacheFile));
- }
- if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) {
- Log().ErrorFile(GenT::GEN, BaseConst().ParseCacheFile,
- "Parse cache file writing failed.");
- return false;
- }
- }
- return true;
- }
- bool cmQtAutoMocUic::CreateDirectories()
- {
- // Create AUTOGEN include directory
- if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) {
- Log().ErrorFile(GenT::GEN, BaseConst().AutogenIncludeDir,
- "Could not create directory.");
- return false;
- }
- return true;
- }
- void cmQtAutoMocUic::Abort(bool error)
- {
- if (error) {
- JobError_.store(true);
- }
- WorkerPool_.Abort();
- }
- std::string cmQtAutoMocUic::AbsoluteBuildPath(
- cm::string_view relativePath) const
- {
- return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
- }
- std::string cmQtAutoMocUic::AbsoluteIncludePath(
- cm::string_view relativePath) const
- {
- return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
- }
|