Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the qmake application of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "option.h"
30#include "cachekeys.h"
31#include <ioutils.h>
32#include <qdir.h>
33#include <qregexp.h>
34#include <qhash.h>
35#include <qdebug.h>
36#include <qlibraryinfo.h>
37#include <stdlib.h>
38#include <stdarg.h>
39
40QT_BEGIN_NAMESPACE
41
42using namespace QMakeInternal;
43
44EvalHandler Option::evalHandler;
45QMakeGlobals *Option::globals;
46ProFileCache *Option::proFileCache;
47QMakeVfs *Option::vfs;
48QMakeParser *Option::parser;
49
50//convenience
51QString Option::prf_ext;
52QString Option::prl_ext;
53QString Option::libtool_ext;
54QString Option::pkgcfg_ext;
55QString Option::ui_ext;
56QStringList Option::h_ext;
57QString Option::cpp_moc_ext;
58QStringList Option::cpp_ext;
59QStringList Option::c_ext;
60QString Option::objc_ext;
61QString Option::objcpp_ext;
62QString Option::obj_ext;
63QString Option::lex_ext;
64QString Option::yacc_ext;
65QString Option::pro_ext;
66QString Option::dir_sep;
67QString Option::h_moc_mod;
68QString Option::yacc_mod;
69QString Option::lex_mod;
70QString Option::res_ext;
71char Option::field_sep;
72
73//mode
74Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
75
76//all modes
77int Option::warn_level = WarnLogic | WarnDeprecated;
78int Option::debug_level = 0;
79QFile Option::output;
80QString Option::output_dir;
81bool Option::recursive = false;
82
83//QMAKE_*_PROPERTY stuff
84QStringList Option::prop::properties;
85
86//QMAKE_GENERATE_PROJECT stuff
87bool Option::projfile::do_pwd = true;
88QStringList Option::projfile::project_dirs;
89
90//QMAKE_GENERATE_MAKEFILE stuff
91int Option::mkfile::cachefile_depth = -1;
92bool Option::mkfile::do_deps = true;
93bool Option::mkfile::do_mocs = true;
94bool Option::mkfile::do_dep_heuristics = true;
95bool Option::mkfile::do_preprocess = false;
96bool Option::mkfile::do_stub_makefile = false;
97QStringList Option::mkfile::project_files;
98
99static Option::QMAKE_MODE default_mode(QString progname)
100{
101 int s = progname.lastIndexOf(QDir::separator());
102 if(s != -1)
103 progname = progname.right(progname.length() - (s + 1));
104 if(progname == "qmakegen")
105 return Option::QMAKE_GENERATE_PROJECT;
106 else if(progname == "qt-config")
107 return Option::QMAKE_QUERY_PROPERTY;
108 return Option::QMAKE_GENERATE_MAKEFILE;
109}
110
111static QString detectProjectFile(const QString &path)
112{
113 QString ret;
114 QDir dir(path);
115 if(dir.exists(dir.dirName() + Option::pro_ext)) {
116 ret = dir.filePath(dir.dirName()) + Option::pro_ext;
117 } else { //last try..
118 QStringList profiles = dir.entryList(QStringList("*" + Option::pro_ext));
119 if(profiles.count() == 1)
120 ret = dir.filePath(profiles.at(0));
121 }
122 return ret;
123}
124
125QString project_builtin_regx();
126bool usage(const char *a0)
127{
128 fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
129 "\n"
130 "QMake has two modes, one mode for generating project files based on\n"
131 "some heuristics, and the other for generating makefiles. Normally you\n"
132 "shouldn't need to specify a mode, as makefile generation is the default\n"
133 "mode for qmake, but you may use this to test qmake on an existing project\n"
134 "\n"
135 "Mode:\n"
136 " -project Put qmake into project file generation mode%s\n"
137 " In this mode qmake interprets files as files to\n"
138 " be built,\n"
139 " defaults to %s\n"
140 " Note: The created .pro file probably will \n"
141 " need to be edited. For example add the QT variable to \n"
142 " specify what modules are required.\n"
143 " -makefile Put qmake into makefile generation mode%s\n"
144 " In this mode qmake interprets files as project files to\n"
145 " be processed, if skipped qmake will try to find a project\n"
146 " file in your current working directory\n"
147 "\n"
148 "Warnings Options:\n"
149 " -Wnone Turn off all warnings; specific ones may be re-enabled by\n"
150 " later -W options\n"
151 " -Wall Turn on all warnings\n"
152 " -Wparser Turn on parser warnings\n"
153 " -Wlogic Turn on logic warnings (on by default)\n"
154 " -Wdeprecated Turn on deprecation warnings (on by default)\n"
155 "\n"
156 "Options:\n"
157 " * You can place any variable assignment in options and it will be *\n"
158 " * processed as if it was in [files]. These assignments will be *\n"
159 " * processed before [files] by default. *\n"
160 " -o file Write output to file\n"
161 " -d Increase debug level\n"
162 " -t templ Overrides TEMPLATE as templ\n"
163 " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
164 " -help This help\n"
165 " -v Version information\n"
166 " -early All subsequent variable assignments will be\n"
167 " parsed right before default_pre.prf\n"
168 " -before All subsequent variable assignments will be\n"
169 " parsed right before [files] (the default)\n"
170 " -after All subsequent variable assignments will be\n"
171 " parsed after [files]\n"
172 " -late All subsequent variable assignments will be\n"
173 " parsed right after default_post.prf\n"
174 " -norecursive Don't do a recursive search\n"
175 " -recursive Do a recursive search\n"
176 " -set <prop> <value> Set persistent property\n"
177 " -unset <prop> Unset persistent property\n"
178 " -query <prop> Query persistent property. Show all if <prop> is empty.\n"
179 " -qtconf file Use file instead of looking for qt.conf\n"
180 " -cache file Use file as cache [makefile mode only]\n"
181 " -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
182 " -nocache Don't use a cache file [makefile mode only]\n"
183 " -nodepend Don't generate dependencies [makefile mode only]\n"
184 " -nomoc Don't generate moc targets [makefile mode only]\n"
185 " -nopwd Don't look for files in pwd [project mode only]\n"
186 ,a0,
187 default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)" : "", project_builtin_regx().toLatin1().constData(),
188 default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""
189 );
190 return false;
191}
192
193int
194Option::parseCommandLine(QStringList &args, QMakeCmdLineParserState &state)
195{
196 enum { ArgNone, ArgOutput } argState = ArgNone;
197 int x = 0;
198 while (x < args.count()) {
199 switch (argState) {
200 case ArgOutput:
201 Option::output.setFileName(args.at(x--));
202 args.erase(args.begin() + x, args.begin() + x + 2);
203 argState = ArgNone;
204 continue;
205 default:
206 QMakeGlobals::ArgumentReturn cmdRet = globals->addCommandLineArguments(state, args, &x);
207 if (cmdRet == QMakeGlobals::ArgumentsOk)
208 break;
209 if (cmdRet == QMakeGlobals::ArgumentMalformed) {
210 fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
211 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
212 }
213 Q_ASSERT(cmdRet == QMakeGlobals::ArgumentUnknown);
214 QString arg = args.at(x);
215 if (arg.startsWith(QLatin1Char('-'))) {
216 if (arg == "-d") {
217 Option::debug_level++;
218 } else if (arg == "-v" || arg == "-version" || arg == "--version") {
219 fprintf(stdout,
220 "QMake version %s\n"
221 "Using Qt version %s in %s\n",
222 QMAKE_VERSION_STR, QT_VERSION_STR,
223 QLibraryInfo::location(QLibraryInfo::LibrariesPath).toLatin1().constData());
224#ifdef QMAKE_OPENSOURCE_VERSION
225 fprintf(stdout, "QMake is Open Source software from The Qt Company Ltd and/or its subsidiary(-ies).\n");
226#endif
227 return Option::QMAKE_CMDLINE_BAIL;
228 } else if (arg == "-h" || arg == "-help" || arg == "--help") {
229 return Option::QMAKE_CMDLINE_SHOW_USAGE;
230 } else if (arg == "-Wall") {
231 Option::warn_level |= WarnAll;
232 } else if (arg == "-Wparser") {
233 Option::warn_level |= WarnParser;
234 } else if (arg == "-Wlogic") {
235 Option::warn_level |= WarnLogic;
236 } else if (arg == "-Wdeprecated") {
237 Option::warn_level |= WarnDeprecated;
238 } else if (arg == "-Wnone") {
239 Option::warn_level = WarnNone;
240 } else if (arg == "-r" || arg == "-recursive") {
241 Option::recursive = true;
242 args.removeAt(x);
243 continue;
244 } else if (arg == "-nr" || arg == "-norecursive") {
245 Option::recursive = false;
246 args.removeAt(x);
247 continue;
248 } else if (arg == "-o" || arg == "-output") {
249 argState = ArgOutput;
250 } else {
251 if (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
252 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
253 if (arg == "-nodepend" || arg == "-nodepends") {
254 Option::mkfile::do_deps = false;
255 } else if (arg == "-nomoc") {
256 Option::mkfile::do_mocs = false;
257 } else if (arg == "-createstub") {
258 Option::mkfile::do_stub_makefile = true;
259 } else if (arg == "-nodependheuristics") {
260 Option::mkfile::do_dep_heuristics = false;
261 } else if (arg == "-E") {
262 Option::mkfile::do_preprocess = true;
263 } else {
264 fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
265 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
266 }
267 } else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
268 if (arg == "-nopwd") {
269 Option::projfile::do_pwd = false;
270 } else {
271 fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
272 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
273 }
274 }
275 }
276 } else {
277 bool handled = true;
278 if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
279 Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
280 Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) {
281 Option::prop::properties.append(arg);
282 } else {
283 QFileInfo fi(arg);
284 if(!fi.makeAbsolute()) //strange
285 arg = fi.filePath();
286 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
287 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
288 if(fi.isDir()) {
289 QString proj = detectProjectFile(arg);
290 if (!proj.isNull())
291 arg = proj;
292 }
293 Option::mkfile::project_files.append(arg);
294 } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
295 Option::projfile::project_dirs.append(arg);
296 } else {
297 handled = false;
298 }
299 }
300 if(!handled) {
301 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
302 }
303 args.removeAt(x);
304 continue;
305 }
306 }
307 x++;
308 }
309 if (argState != ArgNone) {
310 fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
311 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
312 }
313 return Option::QMAKE_CMDLINE_SUCCESS;
314}
315
316int
317Option::init(int argc, char **argv)
318{
319 Option::prf_ext = ".prf";
320 Option::pro_ext = ".pro";
321 Option::field_sep = ' ';
322
323 if(argc && argv) {
324 QString argv0 = argv[0];
325#ifdef Q_OS_WIN
326 if (!argv0.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
327 argv0 += QLatin1String(".exe");
328#endif
329 if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
330 Option::qmake_mode = default_mode(argv0);
331 if (!argv0.isEmpty() && IoUtils::isAbsolutePath(argv0)) {
332 globals->qmake_abslocation = argv0;
333 } else if (argv0.contains(QLatin1Char('/'))
334#ifdef Q_OS_WIN
335 || argv0.contains(QLatin1Char('\\'))
336#endif
337 ) { //relative PWD
338 globals->qmake_abslocation = QDir::current().absoluteFilePath(argv0);
339 } else { //in the PATH
340 QByteArray pEnv = qgetenv("PATH");
341 QDir currentDir = QDir::current();
342#ifdef Q_OS_WIN
343 QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
344 paths.prepend(QLatin1String("."));
345#else
346 QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
347#endif
348 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
349 if ((*p).isEmpty())
350 continue;
351 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
352 if (QFile::exists(candidate)) {
353 globals->qmake_abslocation = candidate;
354 break;
355 }
356 }
357 }
358 if (Q_UNLIKELY(globals->qmake_abslocation.isNull())) {
359 // This is rather unlikely to ever happen on a modern system ...
360 globals->qmake_abslocation = QLibraryInfo::rawLocation(
361 QLibraryInfo::HostBinariesPath,
362 QLibraryInfo::EffectivePaths)
363#ifdef Q_OS_WIN
364 + "/qmake.exe";
365#else
366 + "/qmake";
367#endif
368 } else {
369 globals->qmake_abslocation = QDir::cleanPath(globals->qmake_abslocation);
370 }
371 } else {
372 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
373 }
374
375 QMakeCmdLineParserState cmdstate(QDir::currentPath());
376 const QByteArray envflags = qgetenv("QMAKEFLAGS");
377 if (!envflags.isNull()) {
378 QStringList args;
379 QByteArray buf = "";
380 char quote = 0;
381 bool hasWord = false;
382 for (int i = 0; i < envflags.size(); ++i) {
383 char c = envflags.at(i);
384 if (!quote && (c == '\'' || c == '"')) {
385 quote = c;
386 } else if (c == quote) {
387 quote = 0;
388 } else if (!quote && c == ' ') {
389 if (hasWord) {
390 args << QString::fromLocal8Bit(buf);
391 hasWord = false;
392 buf = "";
393 }
394 } else {
395 buf += c;
396 hasWord = true;
397 }
398 }
399 if (hasWord)
400 args << QString::fromLocal8Bit(buf);
401 parseCommandLine(args, cmdstate);
402 cmdstate.flush();
403 }
404 if(argc && argv) {
405 QStringList args;
406 args.reserve(argc - 1);
407 for (int i = 1; i < argc; i++)
408 args << QString::fromLocal8Bit(argv[i]);
409
410 while (!args.isEmpty()) {
411 QString opt = args.at(0);
412 if (opt == "-project") {
413 Option::recursive = true;
414 Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
415 } else if (opt == "-prl") {
416 Option::mkfile::do_deps = false;
417 Option::mkfile::do_mocs = false;
418 Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
419 } else if (opt == "-set") {
420 Option::qmake_mode = Option::QMAKE_SET_PROPERTY;
421 } else if (opt == "-unset") {
422 Option::qmake_mode = Option::QMAKE_UNSET_PROPERTY;
423 } else if (opt == "-query") {
424 Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY;
425 } else if (opt == "-makefile") {
426 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
427 } else {
428 break;
429 }
430 args.takeFirst();
431 break;
432 }
433
434 int ret = parseCommandLine(args, cmdstate);
435 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
436 if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
437 usage(argv[0]);
438 return ret;
439 //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
440 }
441 globals->qmake_args = args;
442 globals->qmake_extra_args = cmdstate.extraargs;
443 }
444 globals->commitCommandLineArguments(cmdstate);
445 globals->debugLevel = Option::debug_level;
446
447 //last chance for defaults
448 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
449 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
450 globals->useEnvironment();
451
452 //try REALLY hard to do it for them, lazy..
453 if(Option::mkfile::project_files.isEmpty()) {
454 QString proj = detectProjectFile(qmake_getpwd());
455 if(!proj.isNull())
456 Option::mkfile::project_files.append(proj);
457#ifndef QT_BUILD_QMAKE_LIBRARY
458 if(Option::mkfile::project_files.isEmpty()) {
459 usage(argv[0]);
460 return Option::QMAKE_CMDLINE_ERROR;
461 }
462#endif
463 }
464 }
465
466 return QMAKE_CMDLINE_SUCCESS;
467}
468
469void Option::prepareProject(const QString &pfile)
470{
471 // Canonicalize only the directory, otherwise things will go haywire
472 // if the file itself is a symbolic link.
473 const QString srcpath = QFileInfo(QFileInfo(pfile).absolutePath()).canonicalFilePath();
474 globals->setDirectories(srcpath, output_dir);
475}
476
477bool Option::postProcessProject(QMakeProject *project)
478{
479 Option::cpp_ext = project->values("QMAKE_EXT_CPP").toQStringList();
480 Option::h_ext = project->values("QMAKE_EXT_H").toQStringList();
481 Option::c_ext = project->values("QMAKE_EXT_C").toQStringList();
482 Option::objc_ext = project->first("QMAKE_EXT_OBJC").toQString();
483 Option::objcpp_ext = project->first("QMAKE_EXT_OBJCXX").toQString();
484 Option::res_ext = project->first("QMAKE_EXT_RES").toQString();
485 Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG").toQString();
486 Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL").toQString();
487 Option::prl_ext = project->first("QMAKE_EXT_PRL").toQString();
488 Option::ui_ext = project->first("QMAKE_EXT_UI").toQString();
489 Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC").toQString();
490 Option::lex_ext = project->first("QMAKE_EXT_LEX").toQString();
491 Option::yacc_ext = project->first("QMAKE_EXT_YACC").toQString();
492 Option::obj_ext = project->first("QMAKE_EXT_OBJ").toQString();
493 Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC").toQString();
494 Option::lex_mod = project->first("QMAKE_MOD_LEX").toQString();
495 Option::yacc_mod = project->first("QMAKE_MOD_YACC").toQString();
496
497 Option::dir_sep = project->dirSep().toQString();
498
499 if (!project->buildRoot().isEmpty() && Option::output_dir.startsWith(project->buildRoot()))
500 Option::mkfile::cachefile_depth =
501 Option::output_dir.mid(project->buildRoot().length()).count('/');
502
503 return true;
504}
505
506QString
507Option::fixString(QString string, uchar flags)
508{
509 //const QString orig_string = string;
510 static QHash<FixStringCacheKey, QString> *cache = nullptr;
511 if(!cache) {
512 cache = new QHash<FixStringCacheKey, QString>;
513 qmakeAddCacheClear(qmakeDeleteCacheClear<QHash<FixStringCacheKey, QString> >, (void**)&cache);
514 }
515 FixStringCacheKey cacheKey(string, flags);
516
517 QHash<FixStringCacheKey, QString>::const_iterator it = cache->constFind(cacheKey);
518
519 if (it != cache->constEnd()) {
520 //qDebug() << "Fix (cached) " << orig_string << "->" << it.value();
521 return it.value();
522 }
523
524 //fix the environment variables
525 if(flags & Option::FixEnvVars) {
526 int rep;
527 static QRegExp reg_var("\\$\\(.*\\)");
528 reg_var.setMinimal(true);
529 while((rep = reg_var.indexIn(string)) != -1)
530 string.replace(rep, reg_var.matchedLength(),
531 QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
532 }
533
534 //canonicalize it (and treat as a path)
535 if(flags & Option::FixPathCanonicalize) {
536#if 0
537 string = QFileInfo(string).canonicalFilePath();
538#endif
539 string = QDir::cleanPath(string);
540 }
541
542 // either none or only one active flag
543 Q_ASSERT(((flags & Option::FixPathToLocalSeparators) != 0) +
544 ((flags & Option::FixPathToTargetSeparators) != 0) +
545 ((flags & Option::FixPathToNormalSeparators) != 0) <= 1);
546
547 //fix separators
548 if (flags & Option::FixPathToNormalSeparators) {
549 string.replace('\\', '/');
550 } else if (flags & Option::FixPathToLocalSeparators) {
551#if defined(Q_OS_WIN32)
552 string.replace('/', '\\');
553#else
554 string.replace('\\', '/');
555#endif
556 } else if(flags & Option::FixPathToTargetSeparators) {
557 string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep);
558 }
559
560 if ((string.startsWith("\"") && string.endsWith("\"")) ||
561 (string.startsWith("\'") && string.endsWith("\'")))
562 string = string.mid(1, string.length()-2);
563
564 //cache
565 //qDebug() << "Fix" << orig_string << "->" << string;
566 cache->insert(cacheKey, string);
567 return string;
568}
569
570void debug_msg_internal(int level, const char *fmt, ...)
571{
572 if(Option::debug_level < level)
573 return;
574 fprintf(stderr, "DEBUG %d: ", level);
575 {
576 va_list ap;
577 va_start(ap, fmt);
578 vfprintf(stderr, fmt, ap);
579 va_end(ap);
580 }
581 fprintf(stderr, "\n");
582}
583
584void warn_msg(QMakeWarn type, const char *fmt, ...)
585{
586 if(!(Option::warn_level & type))
587 return;
588 fprintf(stderr, "WARNING: ");
589 {
590 va_list ap;
591 va_start(ap, fmt);
592 vfprintf(stderr, fmt, ap);
593 va_end(ap);
594 }
595 fprintf(stderr, "\n");
596}
597
598void EvalHandler::message(int type, const QString &msg, const QString &fileName, int lineNo)
599{
600 QString pfx;
601 if ((type & QMakeHandler::CategoryMask) == QMakeHandler::WarningMessage) {
602 int code = (type & QMakeHandler::CodeMask);
603 if ((code == QMakeHandler::WarnLanguage && !(Option::warn_level & WarnParser))
604 || (code == QMakeHandler::WarnDeprecated && !(Option::warn_level & WarnDeprecated)))
605 return;
606 pfx = QString::fromLatin1("WARNING: ");
607 }
608 if (lineNo > 0)
609 fprintf(stderr, "%s%s:%d: %s\n", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg));
610 else if (lineNo)
611 fprintf(stderr, "%s%s: %s\n", qPrintable(pfx), qPrintable(fileName), qPrintable(msg));
612 else
613 fprintf(stderr, "%s%s\n", qPrintable(pfx), qPrintable(msg));
614}
615
616void EvalHandler::fileMessage(int type, const QString &msg)
617{
618 Q_UNUSED(type)
619 fprintf(stderr, "%s\n", qPrintable(msg));
620}
621
622void EvalHandler::aboutToEval(ProFile *, ProFile *, EvalFileType)
623{
624}
625
626void EvalHandler::doneWithEval(ProFile *)
627{
628}
629
630class QMakeCacheClearItem {
631private:
632 qmakeCacheClearFunc func;
633 void **data;
634public:
635 QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { }
636 ~QMakeCacheClearItem() {
637 (*func)(*data);
638 *data = nullptr;
639 }
640};
641static QList<QMakeCacheClearItem*> cache_items;
642
643void
644qmakeClearCaches()
645{
646 qDeleteAll(cache_items);
647 cache_items.clear();
648}
649
650void
651qmakeAddCacheClear(qmakeCacheClearFunc func, void **data)
652{
653 cache_items.append(new QMakeCacheClearItem(func, data));
654}
655
656QString qmake_libraryInfoFile()
657{
658 if (!Option::globals->qtconf.isEmpty())
659 return Option::globals->qtconf;
660 if (!Option::globals->qmake_abslocation.isEmpty())
661 return QDir(QFileInfo(Option::globals->qmake_abslocation).absolutePath()).filePath("qt.conf");
662 return QString();
663}
664
665QT_END_NAMESPACE
666

Warning: That file was not part of the compilation database. It may have many parsing errors.