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
|
2012-09-05 16:29:19 +00:00
|
|
|
|
|
|
|
#include "qmakeglobals.h"
|
|
|
|
|
|
|
|
#include "qmakeevaluator.h"
|
|
|
|
#include "ioutils.h"
|
|
|
|
|
|
|
|
#include <qbytearray.h>
|
|
|
|
#include <qdatetime.h>
|
|
|
|
#include <qdebug.h>
|
|
|
|
#include <qdir.h>
|
|
|
|
#include <qfile.h>
|
|
|
|
#include <qfileinfo.h>
|
|
|
|
#include <qlist.h>
|
|
|
|
#include <qset.h>
|
|
|
|
#include <qstack.h>
|
|
|
|
#include <qstring.h>
|
|
|
|
#include <qstringlist.h>
|
|
|
|
#include <qtextstream.h>
|
|
|
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
|
|
|
# include <qthreadpool.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef Q_OS_UNIX
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#else
|
2021-11-19 05:05:38 +00:00
|
|
|
#include <qt_windows.h>
|
2012-09-05 16:29:19 +00:00
|
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN32
|
|
|
|
#define QT_POPEN _popen
|
2016-06-16 13:38:22 +00:00
|
|
|
#define QT_POPEN_READ "rb"
|
2012-09-05 16:29:19 +00:00
|
|
|
#define QT_PCLOSE _pclose
|
|
|
|
#else
|
|
|
|
#define QT_POPEN popen
|
2016-06-16 13:38:22 +00:00
|
|
|
#define QT_POPEN_READ "r"
|
2012-09-05 16:29:19 +00:00
|
|
|
#define QT_PCLOSE pclose
|
|
|
|
#endif
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
2017-07-28 11:25:27 +00:00
|
|
|
using namespace QMakeInternal; // for IoUtils
|
2012-09-05 16:29:19 +00:00
|
|
|
|
|
|
|
#define fL1S(s) QString::fromLatin1(s)
|
|
|
|
|
|
|
|
QMakeGlobals::QMakeGlobals()
|
|
|
|
{
|
|
|
|
do_cache = true;
|
|
|
|
|
|
|
|
#ifdef PROEVALUATOR_DEBUG
|
|
|
|
debugLevel = 0;
|
|
|
|
#endif
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
dirlist_sep = QLatin1Char(';');
|
|
|
|
dir_sep = QLatin1Char('\\');
|
|
|
|
#else
|
|
|
|
dirlist_sep = QLatin1Char(':');
|
|
|
|
dir_sep = QLatin1Char('/');
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
QMakeGlobals::~QMakeGlobals()
|
|
|
|
{
|
|
|
|
qDeleteAll(baseEnvs);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &spec)
|
|
|
|
{
|
|
|
|
QString ret = QDir::cleanPath(spec);
|
|
|
|
if (ret.contains(QLatin1Char('/'))) {
|
2017-07-28 11:25:27 +00:00
|
|
|
QString absRet = IoUtils::resolvePath(state.pwd, ret);
|
2012-09-05 16:29:19 +00:00
|
|
|
if (QFile::exists(absRet))
|
2017-07-28 11:25:27 +00:00
|
|
|
ret = absRet;
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-04-23 13:42:15 +00:00
|
|
|
/*
|
|
|
|
* Return value meanings:
|
|
|
|
* ArgumentUnknown The argument at *pos was not handled by this function.
|
|
|
|
* Leave it to the caller to handle this argument.
|
|
|
|
* ArgumentMalformed There was an error detected.
|
|
|
|
* ArgumentsOk All arguments were known. There are no arguments left to handle.
|
|
|
|
*/
|
2012-09-05 16:29:19 +00:00
|
|
|
QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
|
|
|
|
QMakeCmdLineParserState &state, QStringList &args, int *pos)
|
|
|
|
{
|
2015-07-13 09:21:22 +00:00
|
|
|
enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache, ArgQtConf } argState = ArgNone;
|
2012-09-05 16:29:19 +00:00
|
|
|
for (; *pos < args.count(); (*pos)++) {
|
|
|
|
QString arg = args.at(*pos);
|
|
|
|
switch (argState) {
|
|
|
|
case ArgConfig:
|
2017-02-03 17:12:52 +00:00
|
|
|
state.configs[state.phase] << arg;
|
2012-09-05 16:29:19 +00:00
|
|
|
break;
|
|
|
|
case ArgSpec:
|
|
|
|
qmakespec = args[*pos] = cleanSpec(state, arg);
|
|
|
|
break;
|
|
|
|
case ArgXSpec:
|
|
|
|
xqmakespec = args[*pos] = cleanSpec(state, arg);
|
|
|
|
break;
|
|
|
|
case ArgTmpl:
|
|
|
|
user_template = arg;
|
|
|
|
break;
|
|
|
|
case ArgTmplPfx:
|
|
|
|
user_template_prefix = arg;
|
|
|
|
break;
|
|
|
|
case ArgCache:
|
2017-07-28 11:25:27 +00:00
|
|
|
cachefile = args[*pos] = IoUtils::resolvePath(state.pwd, arg);
|
2012-09-05 16:29:19 +00:00
|
|
|
break;
|
2015-07-13 09:21:22 +00:00
|
|
|
case ArgQtConf:
|
2017-07-28 11:25:27 +00:00
|
|
|
qtconf = args[*pos] = IoUtils::resolvePath(state.pwd, arg);
|
2015-07-13 09:21:22 +00:00
|
|
|
break;
|
2012-09-05 16:29:19 +00:00
|
|
|
default:
|
|
|
|
if (arg.startsWith(QLatin1Char('-'))) {
|
2016-05-12 15:50:17 +00:00
|
|
|
if (arg == QLatin1String("--")) {
|
|
|
|
state.extraargs = args.mid(*pos + 1);
|
2017-01-03 18:10:14 +00:00
|
|
|
args.erase(args.begin() + *pos, args.end());
|
2016-05-12 15:50:17 +00:00
|
|
|
return ArgumentsOk;
|
|
|
|
}
|
2017-02-03 17:12:52 +00:00
|
|
|
if (arg == QLatin1String("-early"))
|
|
|
|
state.phase = QMakeEvalEarly;
|
|
|
|
else if (arg == QLatin1String("-before"))
|
|
|
|
state.phase = QMakeEvalBefore;
|
|
|
|
else if (arg == QLatin1String("-after"))
|
|
|
|
state.phase = QMakeEvalAfter;
|
|
|
|
else if (arg == QLatin1String("-late"))
|
|
|
|
state.phase = QMakeEvalLate;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-config"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgConfig;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-nocache"))
|
2012-09-05 16:29:19 +00:00
|
|
|
do_cache = false;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-cache"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgCache;
|
2015-07-13 09:21:22 +00:00
|
|
|
else if (arg == QLatin1String("-qtconf"))
|
|
|
|
argState = ArgQtConf;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-platform") || arg == QLatin1String("-spec"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgSpec;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-xplatform") || arg == QLatin1String("-xspec"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgXSpec;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-template") || arg == QLatin1String("-t"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgTmpl;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-template_prefix") || arg == QLatin1String("-tp"))
|
2012-09-05 16:29:19 +00:00
|
|
|
argState = ArgTmplPfx;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-win32"))
|
2012-09-05 16:29:19 +00:00
|
|
|
dir_sep = QLatin1Char('\\');
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else if (arg == QLatin1String("-unix"))
|
2012-09-05 16:29:19 +00:00
|
|
|
dir_sep = QLatin1Char('/');
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
(cherry picked from qtcreator/29a93998df8405e8799ad23934a56cd99fb36403)
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
2013-01-08 01:32:53 +00:00
|
|
|
else
|
2012-09-05 16:29:19 +00:00
|
|
|
return ArgumentUnknown;
|
|
|
|
} else if (arg.contains(QLatin1Char('='))) {
|
2017-02-03 17:12:52 +00:00
|
|
|
state.cmds[state.phase] << arg;
|
2012-09-05 16:29:19 +00:00
|
|
|
} else {
|
|
|
|
return ArgumentUnknown;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
argState = ArgNone;
|
|
|
|
}
|
|
|
|
if (argState != ArgNone)
|
|
|
|
return ArgumentMalformed;
|
|
|
|
return ArgumentsOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
|
|
|
|
{
|
2016-05-12 15:50:17 +00:00
|
|
|
if (!state.extraargs.isEmpty()) {
|
|
|
|
QString extra = fL1S("QMAKE_EXTRA_ARGS =");
|
|
|
|
for (const QString &ea : qAsConst(state.extraargs))
|
|
|
|
extra += QLatin1Char(' ') + QMakeEvaluator::quoteValue(ProString(ea));
|
2017-02-03 17:12:52 +00:00
|
|
|
state.cmds[QMakeEvalBefore] << extra;
|
|
|
|
}
|
|
|
|
for (int p = 0; p < 4; p++) {
|
|
|
|
if (!state.configs[p].isEmpty())
|
|
|
|
state.cmds[p] << (fL1S("CONFIG += ") + state.configs[p].join(QLatin1Char(' ')));
|
|
|
|
extra_cmds[p] = state.cmds[p].join(QLatin1Char('\n'));
|
2016-05-12 15:50:17 +00:00
|
|
|
}
|
2012-09-05 16:29:19 +00:00
|
|
|
|
|
|
|
if (xqmakespec.isEmpty())
|
|
|
|
xqmakespec = qmakespec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QMakeGlobals::useEnvironment()
|
|
|
|
{
|
|
|
|
if (xqmakespec.isEmpty())
|
|
|
|
xqmakespec = getEnv(QLatin1String("XQMAKESPEC"));
|
|
|
|
if (qmakespec.isEmpty()) {
|
|
|
|
qmakespec = getEnv(QLatin1String("QMAKESPEC"));
|
|
|
|
if (xqmakespec.isEmpty())
|
|
|
|
xqmakespec = qmakespec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QMakeGlobals::setCommandLineArguments(const QString &pwd, const QStringList &_args)
|
|
|
|
{
|
|
|
|
QStringList args = _args;
|
|
|
|
|
|
|
|
QMakeCmdLineParserState state(pwd);
|
|
|
|
for (int pos = 0; pos < args.size(); pos++)
|
|
|
|
addCommandLineArguments(state, args, &pos);
|
|
|
|
commitCommandLineArguments(state);
|
|
|
|
useEnvironment();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir)
|
|
|
|
{
|
|
|
|
if (input_dir != output_dir && !output_dir.isEmpty()) {
|
|
|
|
QString srcpath = input_dir;
|
|
|
|
if (!srcpath.endsWith(QLatin1Char('/')))
|
|
|
|
srcpath += QLatin1Char('/');
|
|
|
|
QString dstpath = output_dir;
|
|
|
|
if (!dstpath.endsWith(QLatin1Char('/')))
|
|
|
|
dstpath += QLatin1Char('/');
|
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
|
|
|
int srcLen = srcpath.size();
|
|
|
|
int dstLen = dstpath.size();
|
2012-09-05 16:29:19 +00:00
|
|
|
int lastSl = -1;
|
2013-07-03 14:54:44 +00:00
|
|
|
while (++lastSl, --srcLen, --dstLen,
|
|
|
|
srcLen && dstLen && srcpath.at(srcLen) == dstpath.at(dstLen))
|
2012-09-05 16:29:19 +00:00
|
|
|
if (srcpath.at(srcLen) == QLatin1Char('/'))
|
|
|
|
lastSl = 0;
|
|
|
|
source_root = srcpath.left(srcLen + lastSl);
|
|
|
|
build_root = dstpath.left(dstLen + lastSl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QMakeGlobals::shadowedPath(const QString &fileName) const
|
|
|
|
{
|
|
|
|
if (source_root.isEmpty())
|
|
|
|
return fileName;
|
|
|
|
if (fileName.startsWith(source_root)
|
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
|
|
|
&& (fileName.size() == source_root.size()
|
|
|
|
|| fileName.at(source_root.size()) == QLatin1Char('/'))) {
|
|
|
|
return build_root + fileName.mid(source_root.size());
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
2013-09-05 16:30:05 +00:00
|
|
|
QStringList QMakeGlobals::splitPathList(const QString &val) const
|
|
|
|
{
|
|
|
|
QStringList ret;
|
|
|
|
if (!val.isEmpty()) {
|
2017-07-28 11:25:27 +00:00
|
|
|
QString cwd(QDir::currentPath());
|
2020-02-25 16:19:30 +00:00
|
|
|
const QStringList vals = val.split(dirlist_sep, Qt::SkipEmptyParts);
|
2013-09-05 16:30:05 +00:00
|
|
|
ret.reserve(vals.length());
|
2016-01-26 13:38:54 +00:00
|
|
|
for (const QString &it : vals)
|
2017-07-28 11:25:27 +00:00
|
|
|
ret << IoUtils::resolvePath(cwd, it);
|
2013-09-05 16:30:05 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-09-05 16:29:19 +00:00
|
|
|
QString QMakeGlobals::getEnv(const QString &var) const
|
|
|
|
{
|
|
|
|
#ifdef PROEVALUATOR_SETENV
|
|
|
|
return environment.value(var);
|
|
|
|
#else
|
|
|
|
return QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData()));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList QMakeGlobals::getPathListEnv(const QString &var) const
|
|
|
|
{
|
2013-09-05 16:30:05 +00:00
|
|
|
return splitPathList(getEnv(var));
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString QMakeGlobals::expandEnvVars(const QString &str) const
|
|
|
|
{
|
|
|
|
QString string = str;
|
2014-09-09 13:16:27 +00:00
|
|
|
int startIndex = 0;
|
|
|
|
forever {
|
|
|
|
startIndex = string.indexOf(QLatin1Char('$'), startIndex);
|
|
|
|
if (startIndex < 0)
|
|
|
|
break;
|
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
|
|
|
if (string.size() < startIndex + 3)
|
2014-09-09 13:16:27 +00:00
|
|
|
break;
|
|
|
|
if (string.at(startIndex + 1) != QLatin1Char('(')) {
|
|
|
|
startIndex++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
int endIndex = string.indexOf(QLatin1Char(')'), startIndex + 2);
|
|
|
|
if (endIndex < 0)
|
|
|
|
break;
|
|
|
|
QString value = getEnv(string.mid(startIndex + 2, endIndex - startIndex - 2));
|
|
|
|
string.replace(startIndex, endIndex - startIndex + 1, value);
|
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
|
|
|
startIndex += value.size();
|
2014-09-09 13:16:27 +00:00
|
|
|
}
|
2012-09-05 16:29:19 +00:00
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef QT_BUILD_QMAKE
|
|
|
|
#ifdef PROEVALUATOR_INIT_PROPS
|
|
|
|
bool QMakeGlobals::initProperties()
|
|
|
|
{
|
|
|
|
QByteArray data;
|
2020-11-24 11:57:28 +00:00
|
|
|
#if QT_CONFIG(process)
|
2012-09-05 16:29:19 +00:00
|
|
|
QProcess proc;
|
|
|
|
proc.start(qmake_abslocation, QStringList() << QLatin1String("-query"));
|
|
|
|
if (!proc.waitForFinished())
|
|
|
|
return false;
|
|
|
|
data = proc.readAll();
|
|
|
|
#else
|
2017-07-28 11:25:27 +00:00
|
|
|
if (FILE *proc = QT_POPEN(QString(IoUtils::shellQuote(qmake_abslocation)
|
2016-06-16 13:38:22 +00:00
|
|
|
+ QLatin1String(" -query")).toLocal8Bit(), QT_POPEN_READ)) {
|
2012-09-05 16:29:19 +00:00
|
|
|
char buff[1024];
|
|
|
|
while (!feof(proc))
|
|
|
|
data.append(buff, int(fread(buff, 1, 1023, proc)));
|
|
|
|
QT_PCLOSE(proc);
|
|
|
|
}
|
|
|
|
#endif
|
2017-01-23 14:58:55 +00:00
|
|
|
parseProperties(data, properties);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void QMakeGlobals::parseProperties(const QByteArray &data, QHash<ProKey, ProString> &properties)
|
|
|
|
{
|
2016-01-26 13:38:54 +00:00
|
|
|
const auto lines = data.split('\n');
|
|
|
|
for (QByteArray line : lines) {
|
2013-06-11 14:08:30 +00:00
|
|
|
int off = line.indexOf(':');
|
|
|
|
if (off < 0) // huh?
|
|
|
|
continue;
|
|
|
|
if (line.endsWith('\r'))
|
|
|
|
line.chop(1);
|
|
|
|
QString name = QString::fromLatin1(line.left(off));
|
|
|
|
ProString value = ProString(QDir::fromNativeSeparators(
|
|
|
|
QString::fromLocal8Bit(line.mid(off + 1))));
|
2017-01-23 14:58:55 +00:00
|
|
|
if (value.isNull())
|
|
|
|
value = ProString(""); // Make sure it is not null, to discern from missing keys
|
2013-06-11 14:08:30 +00:00
|
|
|
properties.insert(ProKey(name), value);
|
|
|
|
if (name.startsWith(QLatin1String("QT_"))) {
|
2017-01-23 14:58:55 +00:00
|
|
|
enum { PropPut, PropRaw, PropGet } variant;
|
|
|
|
if (name.contains(QLatin1Char('/'))) {
|
|
|
|
if (name.endsWith(QLatin1String("/raw")))
|
|
|
|
variant = PropRaw;
|
|
|
|
else if (name.endsWith(QLatin1String("/get")))
|
|
|
|
variant = PropGet;
|
|
|
|
else // Nothing falls back on /src or /dev.
|
2013-06-11 14:08:30 +00:00
|
|
|
continue;
|
|
|
|
name.chop(4);
|
2017-01-23 14:58:55 +00:00
|
|
|
} else {
|
|
|
|
variant = PropPut;
|
2013-06-11 14:08:30 +00:00
|
|
|
}
|
|
|
|
if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
|
2017-01-23 14:58:55 +00:00
|
|
|
if (variant < PropRaw) {
|
|
|
|
if (name == QLatin1String("QT_INSTALL_PREFIX")
|
|
|
|
|| name == QLatin1String("QT_INSTALL_DATA")
|
|
|
|
|| name == QLatin1String("QT_INSTALL_LIBS")
|
|
|
|
|| name == QLatin1String("QT_INSTALL_BINS")) {
|
|
|
|
// Qt4 fallback
|
|
|
|
QString hname = name;
|
|
|
|
hname.replace(3, 7, QLatin1String("HOST"));
|
|
|
|
properties.insert(ProKey(hname), value);
|
|
|
|
properties.insert(ProKey(hname + QLatin1String("/get")), value);
|
|
|
|
properties.insert(ProKey(hname + QLatin1String("/src")), value);
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
2017-01-23 14:58:55 +00:00
|
|
|
properties.insert(ProKey(name + QLatin1String("/raw")), value);
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
2017-01-23 14:58:55 +00:00
|
|
|
if (variant <= PropRaw)
|
|
|
|
properties.insert(ProKey(name + QLatin1String("/dev")), value);
|
|
|
|
} else if (!name.startsWith(QLatin1String("QT_HOST_"))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (variant != PropRaw) {
|
|
|
|
if (variant < PropGet)
|
2013-06-11 14:08:30 +00:00
|
|
|
properties.insert(ProKey(name + QLatin1String("/get")), value);
|
|
|
|
properties.insert(ProKey(name + QLatin1String("/src")), value);
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
|
|
|
}
|
2013-06-11 14:08:30 +00:00
|
|
|
}
|
2012-09-05 16:29:19 +00:00
|
|
|
}
|
|
|
|
#endif // QT_BUILD_QMAKE
|
|
|
|
|
|
|
|
QT_END_NAMESPACE
|