2022-05-10 10:06:48 +00:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
#include "option.h"
|
|
|
|
#include "cachekeys.h"
|
2017-07-28 11:25:41 +00:00
|
|
|
#include <ioutils.h>
|
2011-04-27 10:05:43 +00:00
|
|
|
#include <qdir.h>
|
2020-04-03 15:11:36 +00:00
|
|
|
#include <qregularexpression.h>
|
2011-04-27 10:05:43 +00:00
|
|
|
#include <qhash.h>
|
|
|
|
#include <qdebug.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
2021-03-15 13:25:34 +00:00
|
|
|
#include <qmakelibraryinfo.h>
|
2022-12-06 06:50:20 +00:00
|
|
|
#include <qtversion.h>
|
2021-03-15 13:25:34 +00:00
|
|
|
#include <private/qlibraryinfo_p.h>
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
2017-07-28 11:25:41 +00:00
|
|
|
using namespace QMakeInternal;
|
|
|
|
|
2012-09-05 16:29:19 +00:00
|
|
|
EvalHandler Option::evalHandler;
|
|
|
|
QMakeGlobals *Option::globals;
|
|
|
|
ProFileCache *Option::proFileCache;
|
2013-05-29 18:18:51 +00:00
|
|
|
QMakeVfs *Option::vfs;
|
2012-09-05 16:29:19 +00:00
|
|
|
QMakeParser *Option::parser;
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
//convenience
|
|
|
|
QString Option::prf_ext;
|
|
|
|
QString Option::prl_ext;
|
|
|
|
QString Option::libtool_ext;
|
|
|
|
QString Option::pkgcfg_ext;
|
|
|
|
QString Option::ui_ext;
|
|
|
|
QStringList Option::h_ext;
|
|
|
|
QString Option::cpp_moc_ext;
|
|
|
|
QStringList Option::cpp_ext;
|
|
|
|
QStringList Option::c_ext;
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
QString Option::objc_ext;
|
|
|
|
QString Option::objcpp_ext;
|
2011-04-27 10:05:43 +00:00
|
|
|
QString Option::obj_ext;
|
|
|
|
QString Option::lex_ext;
|
|
|
|
QString Option::yacc_ext;
|
|
|
|
QString Option::pro_ext;
|
|
|
|
QString Option::dir_sep;
|
|
|
|
QString Option::h_moc_mod;
|
|
|
|
QString Option::yacc_mod;
|
|
|
|
QString Option::lex_mod;
|
|
|
|
QString Option::res_ext;
|
|
|
|
char Option::field_sep;
|
|
|
|
|
|
|
|
//mode
|
|
|
|
Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
|
|
|
|
|
|
|
|
//all modes
|
|
|
|
int Option::warn_level = WarnLogic | WarnDeprecated;
|
|
|
|
int Option::debug_level = 0;
|
|
|
|
QFile Option::output;
|
|
|
|
QString Option::output_dir;
|
2012-05-04 18:02:35 +00:00
|
|
|
bool Option::recursive = false;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//QMAKE_*_PROPERTY stuff
|
|
|
|
QStringList Option::prop::properties;
|
|
|
|
|
|
|
|
//QMAKE_GENERATE_PROJECT stuff
|
|
|
|
bool Option::projfile::do_pwd = true;
|
|
|
|
QStringList Option::projfile::project_dirs;
|
|
|
|
|
|
|
|
//QMAKE_GENERATE_MAKEFILE stuff
|
|
|
|
int Option::mkfile::cachefile_depth = -1;
|
|
|
|
bool Option::mkfile::do_deps = true;
|
|
|
|
bool Option::mkfile::do_mocs = true;
|
|
|
|
bool Option::mkfile::do_dep_heuristics = true;
|
|
|
|
bool Option::mkfile::do_preprocess = false;
|
|
|
|
QStringList Option::mkfile::project_files;
|
|
|
|
|
|
|
|
static Option::QMAKE_MODE default_mode(QString progname)
|
|
|
|
{
|
|
|
|
int s = progname.lastIndexOf(QDir::separator());
|
|
|
|
if(s != -1)
|
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
|
|
|
progname = progname.right(progname.size() - (s + 1));
|
2011-04-27 10:05:43 +00:00
|
|
|
if(progname == "qmakegen")
|
|
|
|
return Option::QMAKE_GENERATE_PROJECT;
|
|
|
|
else if(progname == "qt-config")
|
|
|
|
return Option::QMAKE_QUERY_PROPERTY;
|
|
|
|
return Option::QMAKE_GENERATE_MAKEFILE;
|
|
|
|
}
|
|
|
|
|
2022-01-27 14:54:30 +00:00
|
|
|
static QString detectProjectFile(const QString &path, QString *singleProFileCandidate = nullptr)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
QString ret;
|
|
|
|
QDir dir(path);
|
2022-01-27 14:54:30 +00:00
|
|
|
const QString candidate = dir.filePath(dir.dirName() + Option::pro_ext);
|
|
|
|
if (singleProFileCandidate)
|
|
|
|
*singleProFileCandidate = candidate;
|
|
|
|
if (QFile::exists(candidate)) {
|
|
|
|
ret = candidate;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else { //last try..
|
|
|
|
QStringList profiles = dir.entryList(QStringList("*" + Option::pro_ext));
|
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
|
|
|
if(profiles.size() == 1)
|
2011-04-27 10:05:43 +00:00
|
|
|
ret = dir.filePath(profiles.at(0));
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool usage(const char *a0)
|
|
|
|
{
|
|
|
|
fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
|
|
|
|
"\n"
|
|
|
|
"QMake has two modes, one mode for generating project files based on\n"
|
|
|
|
"some heuristics, and the other for generating makefiles. Normally you\n"
|
|
|
|
"shouldn't need to specify a mode, as makefile generation is the default\n"
|
|
|
|
"mode for qmake, but you may use this to test qmake on an existing project\n"
|
|
|
|
"\n"
|
|
|
|
"Mode:\n"
|
|
|
|
" -project Put qmake into project file generation mode%s\n"
|
2019-08-16 20:01:09 +00:00
|
|
|
" In this mode qmake interprets [files] as files to\n"
|
|
|
|
" be added to the .pro file. By default, all files with\n"
|
|
|
|
" known source extensions are added.\n"
|
2011-04-27 10:05:43 +00:00
|
|
|
" Note: The created .pro file probably will \n"
|
|
|
|
" need to be edited. For example add the QT variable to \n"
|
|
|
|
" specify what modules are required.\n"
|
|
|
|
" -makefile Put qmake into makefile generation mode%s\n"
|
|
|
|
" In this mode qmake interprets files as project files to\n"
|
|
|
|
" be processed, if skipped qmake will try to find a project\n"
|
|
|
|
" file in your current working directory\n"
|
|
|
|
"\n"
|
|
|
|
"Warnings Options:\n"
|
|
|
|
" -Wnone Turn off all warnings; specific ones may be re-enabled by\n"
|
|
|
|
" later -W options\n"
|
|
|
|
" -Wall Turn on all warnings\n"
|
|
|
|
" -Wparser Turn on parser warnings\n"
|
|
|
|
" -Wlogic Turn on logic warnings (on by default)\n"
|
|
|
|
" -Wdeprecated Turn on deprecation warnings (on by default)\n"
|
|
|
|
"\n"
|
|
|
|
"Options:\n"
|
2017-02-03 17:12:52 +00:00
|
|
|
" * You can place any variable assignment in options and it will be *\n"
|
|
|
|
" * processed as if it was in [files]. These assignments will be *\n"
|
|
|
|
" * processed before [files] by default. *\n"
|
2011-04-27 10:05:43 +00:00
|
|
|
" -o file Write output to file\n"
|
|
|
|
" -d Increase debug level\n"
|
|
|
|
" -t templ Overrides TEMPLATE as templ\n"
|
|
|
|
" -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
|
|
|
|
" -help This help\n"
|
|
|
|
" -v Version information\n"
|
2017-02-03 17:12:52 +00:00
|
|
|
" -early All subsequent variable assignments will be\n"
|
|
|
|
" parsed right before default_pre.prf\n"
|
|
|
|
" -before All subsequent variable assignments will be\n"
|
|
|
|
" parsed right before [files] (the default)\n"
|
|
|
|
" -after All subsequent variable assignments will be\n"
|
2011-04-27 10:05:43 +00:00
|
|
|
" parsed after [files]\n"
|
2017-02-03 17:12:52 +00:00
|
|
|
" -late All subsequent variable assignments will be\n"
|
|
|
|
" parsed right after default_post.prf\n"
|
2011-04-27 10:05:43 +00:00
|
|
|
" -norecursive Don't do a recursive search\n"
|
|
|
|
" -recursive Do a recursive search\n"
|
|
|
|
" -set <prop> <value> Set persistent property\n"
|
|
|
|
" -unset <prop> Unset persistent property\n"
|
|
|
|
" -query <prop> Query persistent property. Show all if <prop> is empty.\n"
|
2017-07-10 16:28:29 +00:00
|
|
|
" -qtconf file Use file instead of looking for qt" QT_STRINGIFY(QT_VERSION_MAJOR) ".conf, then qt.conf\n"
|
2011-04-27 10:05:43 +00:00
|
|
|
" -cache file Use file as cache [makefile mode only]\n"
|
|
|
|
" -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
|
|
|
|
" -nocache Don't use a cache file [makefile mode only]\n"
|
|
|
|
" -nodepend Don't generate dependencies [makefile mode only]\n"
|
|
|
|
" -nomoc Don't generate moc targets [makefile mode only]\n"
|
|
|
|
" -nopwd Don't look for files in pwd [project mode only]\n"
|
|
|
|
,a0,
|
2019-08-16 20:01:09 +00:00
|
|
|
default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)" : "",
|
2011-04-27 10:05:43 +00:00
|
|
|
default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""
|
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2013-01-30 17:37:11 +00:00
|
|
|
Option::parseCommandLine(QStringList &args, QMakeCmdLineParserState &state)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2012-09-05 16:29:19 +00:00
|
|
|
enum { ArgNone, ArgOutput } argState = ArgNone;
|
|
|
|
int x = 0;
|
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
|
|
|
while (x < args.size()) {
|
2012-09-05 16:29:19 +00:00
|
|
|
switch (argState) {
|
|
|
|
case ArgOutput:
|
|
|
|
Option::output.setFileName(args.at(x--));
|
|
|
|
args.erase(args.begin() + x, args.begin() + x + 2);
|
|
|
|
argState = ArgNone;
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
QMakeGlobals::ArgumentReturn cmdRet = globals->addCommandLineArguments(state, args, &x);
|
|
|
|
if (cmdRet == QMakeGlobals::ArgumentMalformed) {
|
|
|
|
fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
2022-01-28 21:41:17 +00:00
|
|
|
if (!globals->qtconf.isEmpty())
|
|
|
|
QLibraryInfoPrivate::qtconfManualPath = &globals->qtconf;
|
2021-04-23 13:42:15 +00:00
|
|
|
if (cmdRet == QMakeGlobals::ArgumentsOk)
|
|
|
|
break;
|
2012-09-05 16:29:19 +00:00
|
|
|
Q_ASSERT(cmdRet == QMakeGlobals::ArgumentUnknown);
|
|
|
|
QString arg = args.at(x);
|
|
|
|
if (arg.startsWith(QLatin1Char('-'))) {
|
|
|
|
if (arg == "-d") {
|
|
|
|
Option::debug_level++;
|
|
|
|
} else if (arg == "-v" || arg == "-version" || arg == "--version") {
|
|
|
|
fprintf(stdout,
|
|
|
|
"QMake version %s\n"
|
|
|
|
"Using Qt version %s in %s\n",
|
2022-05-03 15:07:40 +00:00
|
|
|
QMAKE_VERSION_STR, qVersion(),
|
2021-01-28 15:06:26 +00:00
|
|
|
QMakeLibraryInfo::path(QLibraryInfo::LibrariesPath)
|
|
|
|
.toLatin1()
|
|
|
|
.constData());
|
2011-04-27 10:05:43 +00:00
|
|
|
#ifdef QMAKE_OPENSOURCE_VERSION
|
2015-01-28 08:44:43 +00:00
|
|
|
fprintf(stdout, "QMake is Open Source software from The Qt Company Ltd and/or its subsidiary(-ies).\n");
|
2011-04-27 10:05:43 +00:00
|
|
|
#endif
|
2012-09-05 16:29:19 +00:00
|
|
|
return Option::QMAKE_CMDLINE_BAIL;
|
|
|
|
} else if (arg == "-h" || arg == "-help" || arg == "--help") {
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE;
|
|
|
|
} else if (arg == "-Wall") {
|
|
|
|
Option::warn_level |= WarnAll;
|
|
|
|
} else if (arg == "-Wparser") {
|
|
|
|
Option::warn_level |= WarnParser;
|
|
|
|
} else if (arg == "-Wlogic") {
|
|
|
|
Option::warn_level |= WarnLogic;
|
|
|
|
} else if (arg == "-Wdeprecated") {
|
|
|
|
Option::warn_level |= WarnDeprecated;
|
|
|
|
} else if (arg == "-Wnone") {
|
|
|
|
Option::warn_level = WarnNone;
|
|
|
|
} else if (arg == "-r" || arg == "-recursive") {
|
|
|
|
Option::recursive = true;
|
|
|
|
args.removeAt(x);
|
|
|
|
continue;
|
|
|
|
} else if (arg == "-nr" || arg == "-norecursive") {
|
|
|
|
Option::recursive = false;
|
|
|
|
args.removeAt(x);
|
|
|
|
continue;
|
|
|
|
} else if (arg == "-o" || arg == "-output") {
|
|
|
|
argState = ArgOutput;
|
|
|
|
} else {
|
|
|
|
if (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
|
|
|
|
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
|
|
|
|
if (arg == "-nodepend" || arg == "-nodepends") {
|
|
|
|
Option::mkfile::do_deps = false;
|
|
|
|
} else if (arg == "-nomoc") {
|
|
|
|
Option::mkfile::do_mocs = false;
|
|
|
|
} else if (arg == "-nodependheuristics") {
|
|
|
|
Option::mkfile::do_dep_heuristics = false;
|
|
|
|
} else if (arg == "-E") {
|
|
|
|
Option::mkfile::do_preprocess = true;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
|
|
|
} else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
|
|
|
|
if (arg == "-nopwd") {
|
|
|
|
Option::projfile::do_pwd = false;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "***Unknown option %s\n", arg.toLatin1().constData());
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bool handled = true;
|
|
|
|
if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
|
|
|
|
Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
|
|
|
|
Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) {
|
|
|
|
Option::prop::properties.append(arg);
|
|
|
|
} else {
|
|
|
|
QFileInfo fi(arg);
|
|
|
|
if(!fi.makeAbsolute()) //strange
|
|
|
|
arg = fi.filePath();
|
|
|
|
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
|
|
|
|
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
|
|
|
|
if(fi.isDir()) {
|
2022-01-27 14:54:30 +00:00
|
|
|
QString singleProFileCandidate;
|
|
|
|
QString proj = detectProjectFile(arg, &singleProFileCandidate);
|
|
|
|
if (proj.isNull()) {
|
|
|
|
fprintf(stderr, "***Cannot detect .pro file in directory '%s'.\n\n"
|
|
|
|
"QMake expects the file '%s' "
|
|
|
|
"or exactly one .pro file in the given directory.\n",
|
|
|
|
qUtf8Printable(arg),
|
|
|
|
qUtf8Printable(singleProFileCandidate));
|
|
|
|
return Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
|
|
|
Option::mkfile::project_files.append(proj);
|
|
|
|
} else {
|
|
|
|
Option::mkfile::project_files.append(arg);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
} else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
|
|
|
|
Option::projfile::project_dirs.append(arg);
|
|
|
|
} else {
|
|
|
|
handled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!handled) {
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
2012-08-09 16:54:40 +00:00
|
|
|
args.removeAt(x);
|
|
|
|
continue;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-09 16:45:48 +00:00
|
|
|
x++;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2012-09-05 16:29:19 +00:00
|
|
|
if (argState != ArgNone) {
|
|
|
|
fprintf(stderr, "***Option %s requires a parameter\n", qPrintable(args.at(x - 1)));
|
|
|
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
return Option::QMAKE_CMDLINE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
Option::init(int argc, char **argv)
|
|
|
|
{
|
|
|
|
Option::prf_ext = ".prf";
|
|
|
|
Option::pro_ext = ".pro";
|
|
|
|
Option::field_sep = ' ';
|
|
|
|
|
|
|
|
if(argc && argv) {
|
|
|
|
QString argv0 = argv[0];
|
2016-11-08 16:23:30 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (!argv0.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
|
|
|
|
argv0 += QLatin1String(".exe");
|
|
|
|
#endif
|
2011-04-27 10:05:43 +00:00
|
|
|
if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
|
|
|
|
Option::qmake_mode = default_mode(argv0);
|
2021-02-26 16:01:51 +00:00
|
|
|
globals->qmake_abslocation = IoUtils::binaryAbsLocation(argv0);
|
2017-06-19 16:40:35 +00:00
|
|
|
if (Q_UNLIKELY(globals->qmake_abslocation.isNull())) {
|
|
|
|
// This is rather unlikely to ever happen on a modern system ...
|
2021-01-28 15:06:26 +00:00
|
|
|
globals->qmake_abslocation =
|
|
|
|
QMakeLibraryInfo::rawLocation(QMakeLibraryInfo::HostBinariesPath,
|
|
|
|
QMakeLibraryInfo::EffectivePaths)
|
2021-02-26 16:01:51 +00:00
|
|
|
+ "/qmake"
|
2012-04-23 10:06:59 +00:00
|
|
|
#ifdef Q_OS_WIN
|
2021-02-26 16:01:51 +00:00
|
|
|
".exe"
|
2012-04-23 10:06:59 +00:00
|
|
|
#endif
|
2021-02-26 16:01:51 +00:00
|
|
|
;
|
2017-06-19 16:40:35 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
|
|
|
|
}
|
|
|
|
|
2013-01-30 17:37:11 +00:00
|
|
|
QMakeCmdLineParserState cmdstate(QDir::currentPath());
|
2011-04-27 10:05:43 +00:00
|
|
|
const QByteArray envflags = qgetenv("QMAKEFLAGS");
|
|
|
|
if (!envflags.isNull()) {
|
2012-08-09 16:45:48 +00:00
|
|
|
QStringList args;
|
|
|
|
QByteArray buf = "";
|
|
|
|
char quote = 0;
|
|
|
|
bool hasWord = false;
|
2011-04-27 10:05:43 +00:00
|
|
|
for (int i = 0; i < envflags.size(); ++i) {
|
2012-08-09 16:45:48 +00:00
|
|
|
char c = envflags.at(i);
|
|
|
|
if (!quote && (c == '\'' || c == '"')) {
|
|
|
|
quote = c;
|
|
|
|
} else if (c == quote) {
|
2011-04-27 10:05:43 +00:00
|
|
|
quote = 0;
|
2012-08-09 16:45:48 +00:00
|
|
|
} else if (!quote && c == ' ') {
|
|
|
|
if (hasWord) {
|
|
|
|
args << QString::fromLocal8Bit(buf);
|
|
|
|
hasWord = false;
|
|
|
|
buf = "";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2012-08-09 16:45:48 +00:00
|
|
|
buf += c;
|
|
|
|
hasWord = true;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-09 16:45:48 +00:00
|
|
|
if (hasWord)
|
|
|
|
args << QString::fromLocal8Bit(buf);
|
2013-01-30 17:37:11 +00:00
|
|
|
parseCommandLine(args, cmdstate);
|
|
|
|
cmdstate.flush();
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
if(argc && argv) {
|
2012-08-09 16:45:48 +00:00
|
|
|
QStringList args;
|
2016-02-01 08:49:22 +00:00
|
|
|
args.reserve(argc - 1);
|
2012-08-09 16:45:48 +00:00
|
|
|
for (int i = 1; i < argc; i++)
|
|
|
|
args << QString::fromLocal8Bit(argv[i]);
|
|
|
|
|
2021-04-23 13:42:15 +00:00
|
|
|
qsizetype idx = 0;
|
|
|
|
while (idx < args.size()) {
|
|
|
|
QString opt = args.at(idx);
|
2012-08-09 14:13:56 +00:00
|
|
|
if (opt == "-project") {
|
|
|
|
Option::recursive = true;
|
|
|
|
Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
|
|
|
|
} else if (opt == "-prl") {
|
|
|
|
Option::mkfile::do_deps = false;
|
|
|
|
Option::mkfile::do_mocs = false;
|
|
|
|
Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
|
|
|
|
} else if (opt == "-set") {
|
|
|
|
Option::qmake_mode = Option::QMAKE_SET_PROPERTY;
|
|
|
|
} else if (opt == "-unset") {
|
|
|
|
Option::qmake_mode = Option::QMAKE_UNSET_PROPERTY;
|
|
|
|
} else if (opt == "-query") {
|
|
|
|
Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY;
|
|
|
|
} else if (opt == "-makefile") {
|
|
|
|
Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
|
2020-10-23 08:37:24 +00:00
|
|
|
} else if (opt == "-qtconf") {
|
2021-04-23 13:42:15 +00:00
|
|
|
// Skip "-qtconf <file>" and proceed.
|
|
|
|
++idx;
|
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
|
|
|
if (idx + 1 < args.size())
|
2021-04-23 13:42:15 +00:00
|
|
|
++idx;
|
|
|
|
continue;
|
2012-08-09 14:13:56 +00:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
2021-04-23 13:42:15 +00:00
|
|
|
args.takeAt(idx);
|
2012-08-09 14:13:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-01-30 17:37:11 +00:00
|
|
|
int ret = parseCommandLine(args, cmdstate);
|
2011-04-27 10:05:43 +00:00
|
|
|
if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
|
|
|
|
if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
|
|
|
|
usage(argv[0]);
|
|
|
|
return ret;
|
|
|
|
//return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
|
|
|
|
}
|
2013-10-23 12:02:59 +00:00
|
|
|
globals->qmake_args = args;
|
2017-01-03 18:10:14 +00:00
|
|
|
globals->qmake_extra_args = cmdstate.extraargs;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2013-01-30 17:37:11 +00:00
|
|
|
globals->commitCommandLineArguments(cmdstate);
|
|
|
|
globals->debugLevel = Option::debug_level;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//last chance for defaults
|
|
|
|
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
|
|
|
|
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
|
2012-09-05 16:29:19 +00:00
|
|
|
globals->useEnvironment();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//try REALLY hard to do it for them, lazy..
|
|
|
|
if(Option::mkfile::project_files.isEmpty()) {
|
|
|
|
QString proj = detectProjectFile(qmake_getpwd());
|
|
|
|
if(!proj.isNull())
|
|
|
|
Option::mkfile::project_files.append(proj);
|
|
|
|
if(Option::mkfile::project_files.isEmpty()) {
|
|
|
|
usage(argv[0]);
|
|
|
|
return Option::QMAKE_CMDLINE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-16 15:12:53 +00:00
|
|
|
return QMAKE_CMDLINE_SUCCESS;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2012-05-09 13:29:25 +00:00
|
|
|
void Option::prepareProject(const QString &pfile)
|
|
|
|
{
|
2017-04-03 13:44:36 +00:00
|
|
|
// Canonicalize only the directory, otherwise things will go haywire
|
|
|
|
// if the file itself is a symbolic link.
|
|
|
|
const QString srcpath = QFileInfo(QFileInfo(pfile).absolutePath()).canonicalFilePath();
|
2012-09-05 16:29:19 +00:00
|
|
|
globals->setDirectories(srcpath, output_dir);
|
2012-05-09 13:29:25 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
bool Option::postProcessProject(QMakeProject *project)
|
|
|
|
{
|
2012-09-06 10:21:38 +00:00
|
|
|
Option::cpp_ext = project->values("QMAKE_EXT_CPP").toQStringList();
|
|
|
|
Option::h_ext = project->values("QMAKE_EXT_H").toQStringList();
|
|
|
|
Option::c_ext = project->values("QMAKE_EXT_C").toQStringList();
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
Option::objc_ext = project->first("QMAKE_EXT_OBJC").toQString();
|
|
|
|
Option::objcpp_ext = project->first("QMAKE_EXT_OBJCXX").toQString();
|
2012-09-06 10:21:38 +00:00
|
|
|
Option::res_ext = project->first("QMAKE_EXT_RES").toQString();
|
|
|
|
Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG").toQString();
|
|
|
|
Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL").toQString();
|
|
|
|
Option::prl_ext = project->first("QMAKE_EXT_PRL").toQString();
|
|
|
|
Option::ui_ext = project->first("QMAKE_EXT_UI").toQString();
|
|
|
|
Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC").toQString();
|
|
|
|
Option::lex_ext = project->first("QMAKE_EXT_LEX").toQString();
|
|
|
|
Option::yacc_ext = project->first("QMAKE_EXT_YACC").toQString();
|
|
|
|
Option::obj_ext = project->first("QMAKE_EXT_OBJ").toQString();
|
|
|
|
Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC").toQString();
|
|
|
|
Option::lex_mod = project->first("QMAKE_MOD_LEX").toQString();
|
|
|
|
Option::yacc_mod = project->first("QMAKE_MOD_YACC").toQString();
|
2012-06-12 18:15:41 +00:00
|
|
|
|
2012-09-05 16:29:19 +00:00
|
|
|
Option::dir_sep = project->dirSep().toQString();
|
|
|
|
|
2014-04-14 09:51:02 +00:00
|
|
|
if (!project->buildRoot().isEmpty() && Option::output_dir.startsWith(project->buildRoot()))
|
2012-06-12 18:15:41 +00:00
|
|
|
Option::mkfile::cachefile_depth =
|
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
|
|
|
Option::output_dir.mid(project->buildRoot().size()).count('/');
|
2012-06-12 18:15:41 +00:00
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString
|
|
|
|
Option::fixString(QString string, uchar flags)
|
|
|
|
{
|
|
|
|
//const QString orig_string = string;
|
2018-08-02 22:22:24 +00:00
|
|
|
static QHash<FixStringCacheKey, QString> *cache = nullptr;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!cache) {
|
|
|
|
cache = new QHash<FixStringCacheKey, QString>;
|
|
|
|
qmakeAddCacheClear(qmakeDeleteCacheClear<QHash<FixStringCacheKey, QString> >, (void**)&cache);
|
|
|
|
}
|
|
|
|
FixStringCacheKey cacheKey(string, flags);
|
|
|
|
|
|
|
|
QHash<FixStringCacheKey, QString>::const_iterator it = cache->constFind(cacheKey);
|
|
|
|
|
|
|
|
if (it != cache->constEnd()) {
|
|
|
|
//qDebug() << "Fix (cached) " << orig_string << "->" << it.value();
|
|
|
|
return it.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
//fix the environment variables
|
|
|
|
if(flags & Option::FixEnvVars) {
|
2020-04-03 15:11:36 +00:00
|
|
|
static QRegularExpression reg_var("\\$\\(.*\\)", QRegularExpression::InvertedGreedinessOption);
|
|
|
|
QRegularExpressionMatch match;
|
|
|
|
while ((match = reg_var.match(string)).hasMatch()) {
|
|
|
|
int start = match.capturedStart();
|
|
|
|
int len = match.capturedLength();
|
|
|
|
string.replace(start, len,
|
|
|
|
QString::fromLocal8Bit(qgetenv(string.mid(start + 2, len - 3).toLatin1().constData()).constData()));
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//canonicalize it (and treat as a path)
|
|
|
|
if(flags & Option::FixPathCanonicalize) {
|
|
|
|
#if 0
|
|
|
|
string = QFileInfo(string).canonicalFilePath();
|
|
|
|
#endif
|
|
|
|
string = QDir::cleanPath(string);
|
|
|
|
}
|
|
|
|
|
2011-11-15 08:34:38 +00:00
|
|
|
// either none or only one active flag
|
2013-10-31 15:15:51 +00:00
|
|
|
Q_ASSERT(((flags & Option::FixPathToLocalSeparators) != 0) +
|
|
|
|
((flags & Option::FixPathToTargetSeparators) != 0) +
|
|
|
|
((flags & Option::FixPathToNormalSeparators) != 0) <= 1);
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
//fix separators
|
2011-11-15 08:34:38 +00:00
|
|
|
if (flags & Option::FixPathToNormalSeparators) {
|
2014-11-27 14:02:50 +00:00
|
|
|
string.replace('\\', '/');
|
2011-11-15 08:34:38 +00:00
|
|
|
} else if (flags & Option::FixPathToLocalSeparators) {
|
2011-04-27 10:05:43 +00:00
|
|
|
#if defined(Q_OS_WIN32)
|
2014-11-27 14:02:50 +00:00
|
|
|
string.replace('/', '\\');
|
2011-04-27 10:05:43 +00:00
|
|
|
#else
|
2014-11-27 14:02:50 +00:00
|
|
|
string.replace('\\', '/');
|
2011-04-27 10:05:43 +00:00
|
|
|
#endif
|
|
|
|
} else if(flags & Option::FixPathToTargetSeparators) {
|
2014-11-27 14:02:50 +00:00
|
|
|
string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((string.startsWith("\"") && string.endsWith("\"")) ||
|
|
|
|
(string.startsWith("\'") && string.endsWith("\'")))
|
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
|
|
|
string = string.mid(1, string.size()-2);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//cache
|
|
|
|
//qDebug() << "Fix" << orig_string << "->" << string;
|
|
|
|
cache->insert(cacheKey, string);
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
void debug_msg_internal(int level, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if(Option::debug_level < level)
|
|
|
|
return;
|
|
|
|
fprintf(stderr, "DEBUG %d: ", level);
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void warn_msg(QMakeWarn type, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if(!(Option::warn_level & type))
|
|
|
|
return;
|
|
|
|
fprintf(stderr, "WARNING: ");
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
2012-09-05 16:29:19 +00:00
|
|
|
void EvalHandler::message(int type, const QString &msg, const QString &fileName, int lineNo)
|
|
|
|
{
|
|
|
|
QString pfx;
|
|
|
|
if ((type & QMakeHandler::CategoryMask) == QMakeHandler::WarningMessage) {
|
|
|
|
int code = (type & QMakeHandler::CodeMask);
|
|
|
|
if ((code == QMakeHandler::WarnLanguage && !(Option::warn_level & WarnParser))
|
|
|
|
|| (code == QMakeHandler::WarnDeprecated && !(Option::warn_level & WarnDeprecated)))
|
|
|
|
return;
|
|
|
|
pfx = QString::fromLatin1("WARNING: ");
|
|
|
|
}
|
|
|
|
if (lineNo > 0)
|
|
|
|
fprintf(stderr, "%s%s:%d: %s\n", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg));
|
|
|
|
else if (lineNo)
|
|
|
|
fprintf(stderr, "%s%s: %s\n", qPrintable(pfx), qPrintable(fileName), qPrintable(msg));
|
|
|
|
else
|
|
|
|
fprintf(stderr, "%s%s\n", qPrintable(pfx), qPrintable(msg));
|
|
|
|
}
|
|
|
|
|
2013-09-02 14:43:49 +00:00
|
|
|
void EvalHandler::fileMessage(int type, const QString &msg)
|
2012-09-05 16:29:19 +00:00
|
|
|
{
|
2020-06-27 12:18:09 +00:00
|
|
|
Q_UNUSED(type);
|
2012-09-05 16:29:19 +00:00
|
|
|
fprintf(stderr, "%s\n", qPrintable(msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
void EvalHandler::aboutToEval(ProFile *, ProFile *, EvalFileType)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void EvalHandler::doneWithEval(ProFile *)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
class QMakeCacheClearItem {
|
|
|
|
private:
|
|
|
|
qmakeCacheClearFunc func;
|
|
|
|
void **data;
|
|
|
|
public:
|
|
|
|
QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { }
|
|
|
|
~QMakeCacheClearItem() {
|
|
|
|
(*func)(*data);
|
2018-08-02 22:22:24 +00:00
|
|
|
*data = nullptr;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
};
|
2022-03-17 11:07:44 +00:00
|
|
|
Q_CONSTINIT static QList<QMakeCacheClearItem*> cache_items;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
qmakeClearCaches()
|
|
|
|
{
|
|
|
|
qDeleteAll(cache_items);
|
|
|
|
cache_items.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
qmakeAddCacheClear(qmakeCacheClearFunc func, void **data)
|
|
|
|
{
|
|
|
|
cache_items.append(new QMakeCacheClearItem(func, data));
|
|
|
|
}
|
|
|
|
|
|
|
|
QT_END_NAMESPACE
|