summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
Diffstat (limited to 'qmake')
-rw-r--r--qmake/Makefile.unix8
-rw-r--r--qmake/Makefile.win323
-rw-r--r--qmake/doc/src/qmake-manual.qdoc157
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp16
-rw-r--r--qmake/generators/makefile.cpp11
-rw-r--r--qmake/generators/unix/unixmake2.cpp5
-rw-r--r--qmake/generators/win32/cesdkhandler.cpp368
-rw-r--r--qmake/generators/win32/cesdkhandler.h89
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp40
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp76
-rw-r--r--qmake/library/proitems.cpp13
-rw-r--r--qmake/library/proitems.h3
-rw-r--r--qmake/library/qmakebuiltins.cpp250
-rw-r--r--qmake/library/qmakeevaluator.cpp16
-rw-r--r--qmake/library/qmakeevaluator.h9
-rw-r--r--qmake/library/qmakeglobals.cpp11
-rw-r--r--qmake/library/qmakeglobals.h2
-rw-r--r--qmake/library/qmakeparser.cpp36
-rw-r--r--qmake/library/qmakeparser.h6
-rw-r--r--qmake/project.cpp3
-rw-r--r--qmake/project.h5
-rw-r--r--qmake/qmake.pri6
22 files changed, 403 insertions, 730 deletions
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 9d3ddab6f9..42ad826fd5 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -8,8 +8,7 @@ OBJS=project.o option.o property.o main.o ioutils.o proitems.o \
makefile.o unixmake2.o unixmake.o \
mingw_make.o winmakefile.o projectgenerator.o \
meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
- msvc_vcproj.o msvc_vcxproj.o msvc_nmake.o msvc_objectmodel.o msbuild_objectmodel.o \
- cesdkhandler.o
+ msvc_vcproj.o msvc_vcxproj.o msvc_nmake.o msvc_objectmodel.o msbuild_objectmodel.o
#qt code
QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtextstream.o qiodevice.o \
@@ -36,7 +35,7 @@ DEPEND_SRC = \
$(QMKGENSRC)/mac/pbuilder_pbx.cpp \
$(QMKGENSRC)/win32/winmakefile.cpp \
$(QMKGENSRC)/win32/mingw_make.cpp $(QMKGENSRC)/win32/msvc_nmake.cpp \
- $(QMKGENSRC)/win32/cesdkhandler.cpp $(QMKGENSRC)/mac/xmloutput.cpp \
+ $(QMKGENSRC)/mac/xmloutput.cpp \
$(QMKGENSRC)/win32/msvc_vcproj.cpp $(QMKGENSRC)/win32/msvc_vcxproj.cpp \
$(QMKGENSRC)/win32/msvc_objectmodel.cpp $(QMKGENSRC)/win32/msbuild_objectmodel.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
@@ -208,9 +207,6 @@ msvc_vcxproj.o: $(QMKSRC)/generators/win32/msvc_vcxproj.cpp
msvc_nmake.o: $(QMKSRC)/generators/win32/msvc_nmake.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
-cesdkhandler.o: $(QMKSRC)/generators/win32/cesdkhandler.cpp
- $(CXX) -c -o $@ $(CXXFLAGS) $<
-
pbuilder_pbx.o: $(QMKSRC)/generators/mac/pbuilder_pbx.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 834065ee61..691d43058d 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -68,8 +68,7 @@ OBJS = project.obj main.obj ioutils.obj proitems.obj qmakevfs.obj \
option.obj winmakefile.obj projectgenerator.obj property.obj meta.obj \
makefiledeps.obj metamakefile.obj xmloutput.obj \
msvc_nmake.obj msvc_vcproj.obj msvc_vcxproj.obj \
- msvc_objectmodel.obj msbuild_objectmodel.obj registry.obj \
- cesdkhandler.obj
+ msvc_objectmodel.obj msbuild_objectmodel.obj registry.obj
#qt code
QTOBJS= \
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 8078c377b2..4d958b1a20 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -657,7 +657,7 @@
qmake knows about many of these features, which can be accessed via specific
variables that only take effect on the platforms where they are relevant.
- \section1 OS X and iOS
+ \section1 OS X, iOS and tvOS
Features specific to these platforms include support for creating universal
binaries, frameworks and bundles.
@@ -1439,7 +1439,7 @@
\target QMAKE_BUNDLE_DATA
\section1 QMAKE_BUNDLE_DATA
- \note This variable is used on OS X and iOS only.
+ \note This variable is used on OS X, iOS and tvOS only.
Specifies the data that will be installed with a library
bundle, and is often used to specify a collection of header files.
@@ -1461,7 +1461,7 @@
\section1 QMAKE_BUNDLE_EXTENSION
- \note This variable is used on OS X and iOS only.
+ \note This variable is used on OS X, iOS and tvOS only.
Specifies the extension to be used for library bundles.
This allows frameworks to be created with custom extensions instead of the
@@ -1695,7 +1695,7 @@
\section1 QMAKE_FRAMEWORK_BUNDLE_NAME
- \note This variable is used on OS X and iOS only.
+ \note This variable is used on OS X, iOS and tvOS only.
In a framework project, this variable contains the name to be used for the
framework that is built.
@@ -1709,11 +1709,11 @@
\target QMAKE_FRAMEWORK_VERSION
\section1 QMAKE_FRAMEWORK_VERSION
- \note This variable is used on OS X and iOS only.
+ \note This variable is used on OS X, iOS and tvOS only.
- For projects where the build target is an OS X or iOS framework, this variable
- is used to specify the version number that will be applied to the framework
- that is built.
+ For projects where the build target is an OS X, iOS or tvOS framework, this
+ variable is used to specify the version number that will be applied to the
+ framework that is built.
By default, this variable contains the same value as the \l{#VERSION}{VERSION}
variable.
@@ -1804,10 +1804,10 @@
\target QMAKE_INFO_PLIST
\section1 QMAKE_INFO_PLIST
- \note This variable is used on OS X and iOS platforms only.
+ \note This variable is used on OS X, iOS and tvOS platforms only.
Specifies the name of the property list file, \c{.plist}, you
- would like to include in your OS X and iOS application bundle.
+ would like to include in your OS X, iOS and tvOS application bundle.
In the \c{.plist} file, you can define some variables, e.g., @EXECUTABLE@,
which qmake will replace with the actual executable name. Other variables
@@ -2165,7 +2165,7 @@
the built shared library's \c SONAME identifier. The \c SONAME is the
identifier that the dynamic linker will later use to reference the library.
In general this reference may be a library name or full library path. On OS
- X and iOS, the path may be specified relatively using the following
+ X, iOS and tvOS, the path may be specified relatively using the following
placeholders:
\table
@@ -2854,6 +2854,7 @@
MY_VAR2 will contain '-Lone -Ltwo -Lthree -Lfour -Lfive', and MY_VAR3 will
contain 'three two three'.
+ \target fn_first
\section2 first(variablename)
Returns the first value of \c variablename.
@@ -2862,8 +2863,9 @@
\snippet code/doc_src_qmake-manual.pro 161
- See also \l{last(variablename)}{last()}.
+ See also \l{take_first()}, \l{fn_last}{last()}.
+ \target format_number()
\section2 format_number(number[, options...])
Returns \c number in the format specified by \c options. You can specify the
@@ -2910,6 +2912,7 @@
to empty strings. If you need to encode spaces in \c glue, \c before, or \c
after, you must quote them.
+ \target fn_last
\section2 last(variablename)
Returns the last value of \c variablename.
@@ -2918,7 +2921,7 @@
\snippet code/doc_src_qmake-manual.pro 162
- See also \l{first(variablename)}{first()}.
+ See also \l{take_last()}, \l{fn_first}{first()}.
\section2 list(arg1 [, arg2 ..., argn])
@@ -2939,14 +2942,56 @@
See also \l{upper(arg1 [, arg2 ..., argn])}{upper()}.
- \section2 member(variablename, position)
+ \target member()
+ \section2 member(variablename [, start [, end]])
- Returns the value at the given \c position in the list of items in
- \c variablename.
- If an item cannot be found at the position specified, an empty string is
- returned. \c variablename is the only required field. If not specified,
- \c position defaults to 0, causing the first value in the list to be
- returned.
+ Returns the slice of the list value of \c variablename with the
+ zero-based element indices between \c start and \c end (inclusive).
+
+ If \c start is not given, it defaults to zero. This usage is
+ equivalent to \c $$first(variablename).
+
+ If \c end is not given, it defaults to \c start. This usage represents
+ simple array indexing, as exactly one element will be returned.
+
+ It is also possible to specify start and end in a single argument, with
+ the numbers separated by two periods.
+
+ Negative numbers represent indices starting from the end of the list,
+ with -1 being the last element.
+
+ If either index is out of range, an empty list is returned.
+
+ If \c end is smaller than \c start, the elements are returned
+ in reverse order.
+
+ \note The fact that the end index is inclusive and unordered implies
+ that an empty list will be returned only when an index is invalid
+ (which is implied by the input variable being empty).
+
+ See also \l{str_member()}.
+
+ \target num_add()
+ \section2 num_add(arg1 [, arg2 ..., argn])
+
+ Takes an arbitrary number of numeric arguments and adds them up,
+ returning the sum.
+
+ Subtraction is implicitly supported due to the possibility to simply
+ prepend a minus sign to a numeric value to negate it:
+
+ \code
+ sum = $$num_add($$first, -$$second)
+ \endcode
+
+ If the operand may be already negative, another step is necessary to
+ normalize the number:
+
+ \code
+ second_neg = -$$second
+ second_neg ~= s/^--//
+ sum = $$num_add($$first, $$second_neg)
+ \endcode
\section2 prompt(question)
@@ -3026,14 +3071,25 @@
See also \l{system_quote(arg)}{system_quote()}.
+ \target fn_size
\section2 size(variablename)
Returns the number of values of \c variablename.
+ See also \l{str_size()}.
+
\section2 sort_depends(variablename, prefix)
This is an internal function that you will typically not need.
+ \section2 sorted(variablename)
+
+ Returns the list of values in \c variablename with entries sorted
+ in ascending ASCII order.
+
+ Numerical sorting can be accomplished by zero-padding the values to
+ a fixed length with the help of the \l{format_number()} function.
+
\section2 split(variablename, separator)
Splits the value of \c variablename into separate values, and returns them
@@ -3043,6 +3099,45 @@
\snippet code/doc_src_qmake-manual.pro 168
+ \target str_member()
+ \section2 str_member(arg [, start [, end]])
+
+ This function is identical to \l{member()}, except that it operates
+ on a string value instead of a list variable, and consequently the
+ indices refer to character positions.
+
+ This function can be used to implement many common string slicing
+ operations:
+
+ \code
+ # $$left(VAR, len)
+ left = $$str_member(VAR, 0, $$num_add($$len, -1))
+
+ # $$right(VAR, len)
+ right = $$str_member(VAR, -$$num, -1)
+
+ # $$mid(VAR, off, len)
+ mid = $$str_member(VAR, $$off, $$num_add($$off, $$len, -1))
+
+ # $$mid(VAR, off)
+ mid = $$str_member(VAR, $$off, -1)
+
+ # $$reverse(VAR)
+ reverse = $$str_member(VAR, -1, 0)
+ \endcode
+
+ \note In these implementations, a zero \c len argument needs to be
+ handled separately.
+
+ See also \l{member()}, \l{num_add()}.
+
+ \target str_size()
+ \section2 str_size(arg)
+
+ Returns the number of characters in the argument.
+
+ See also \l{fn_size}{size()}.
+
\section2 system(command[, mode])
You can use this variant of the \c system function to obtain stdout from the
@@ -3070,6 +3165,26 @@
See also \l{shell_quote(arg)}{shell_quote()}.
+ \target take_first()
+ \section2 take_first(variablename)
+
+ Returns the first value of \c variablename and removes it from the
+ source variable.
+
+ This provides convenience for implementing queues, for example.
+
+ See also \l{take_last()}, \l{fn_first}{first()}.
+
+ \target take_last()
+ \section2 take_last(variablename)
+
+ Returns the last value of \c variablename and removes it from the
+ source variable.
+
+ This provides convenience for implementing stacks, for example.
+
+ See also \l{take_first()}, \l{fn_last}{last()}.
+
\target unique
\section2 unique(variablename)
@@ -4308,7 +4423,7 @@
\li nmake
\li Visual Studio projects (VS 2008 and later)
\endlist
- \li OS X and iOS
+ \li OS X, iOS and tvOS
\list
\li Makefile
\li Xcode
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 147c03a92d..47c7826154 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1089,7 +1089,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
// Copy Bundle Data
if (!project->isEmpty("QMAKE_BUNDLE_DATA")) {
ProStringList bundle_file_refs;
- bool ios = project->isActiveConfig("ios");
+ bool osx = project->isActiveConfig("osx");
//all bundle data
const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
@@ -1117,8 +1117,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t};\n";
}
- if (copyBundleResources && ((ios && path.isEmpty())
- || (!ios && path == QLatin1String("Contents/Resources")))) {
+ if (copyBundleResources && ((!osx && path.isEmpty())
+ || (osx && path == QLatin1String("Contents/Resources")))) {
for (const ProString &s : qAsConst(bundle_files))
bundle_resources_files << s;
} else {
@@ -1336,7 +1336,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
ProString targetName = project->first("QMAKE_ORIG_TARGET");
ProString testHost = "$(BUILT_PRODUCTS_DIR)/" + targetName + ".app/";
- if (!project->isActiveConfig("ios"))
+ if (project->isActiveConfig("osx"))
testHost.append("Contents/MacOS/");
testHost.append(targetName);
@@ -1404,10 +1404,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QMap<QString, QString> settings;
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
- // Bitcode is only supported with a deployment target >= iOS 6.0.
- // Disable it for now, and consider switching it on when later
- // bumping the deployment target.
- settings.insert("ENABLE_BITCODE", "NO");
+ // required for tvOS (and watchos), optional on iOS (deployment target >= iOS 6.0)
+ settings.insert("ENABLE_BITCODE", project->isActiveConfig("bitcode") ? "YES" : "NO");
settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
if(!as_release)
settings.insert("GCC_OPTIMIZATION_LEVEL", "0");
@@ -1537,6 +1535,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t\t" << writeSettings("MACOSX_DEPLOYMENT_TARGET", project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET")) << ";\n";
if (!project->isEmpty("QMAKE_IOS_DEPLOYMENT_TARGET"))
t << "\t\t\t\t" << writeSettings("IPHONEOS_DEPLOYMENT_TARGET", project->first("QMAKE_IOS_DEPLOYMENT_TARGET")) << ";\n";
+ if (!project->isEmpty("QMAKE_TVOS_DEPLOYMENT_TARGET"))
+ t << "\t\t\t\t" << writeSettings("APPLETVOS_DEPLOYMENT_TARGET", project->first("QMAKE_TVOS_DEPLOYMENT_TARGET")) << ";\n";
if (!project->isEmpty("QMAKE_XCODE_CODE_SIGN_IDENTITY"))
t << "\t\t\t\t" << writeSettings("CODE_SIGN_IDENTITY", project->first("QMAKE_XCODE_CODE_SIGN_IDENTITY")) << ";\n";
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 12004c62c3..762ae66a1a 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -318,8 +318,8 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString
QDir::NoDotAndDotDot | QDir::AllEntries);
if(files.isEmpty()) {
debug_msg(1, "%s:%d Failure to find %s in vpath (%s)",
- __FILE__, __LINE__,
- val.toLatin1().constData(), vpath.join("::").toLatin1().constData());
+ __FILE__, __LINE__, val.toLatin1().constData(),
+ vpath.join(QString("::")).toLatin1().constData());
if(flags & VPATH_RemoveMissingFiles)
remove_file = true;
else if(flags & VPATH_WarnMissingFiles)
@@ -780,7 +780,8 @@ MakefileGenerator::init()
for (ProStringList::Iterator it = incDirs.begin(); it != incDirs.end(); ++it)
deplist.append(QMakeLocalFileName((*it).toQString()));
QMakeSourceFileInfo::setDependencyPaths(deplist);
- debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").toLatin1().constData());
+ debug_msg(1, "Dependency Directories: %s",
+ incDirs.join(QString(" :: ")).toLatin1().constData());
//cache info
if(project->isActiveConfig("qmake_cache")) {
QString cache_file;
@@ -2183,7 +2184,7 @@ MakefileGenerator::writeExtraVariables(QTextStream &t)
}
if (!outlist.isEmpty()) {
t << "####### Custom Variables\n";
- t << outlist.join("\n") << endl << endl;
+ t << outlist.join('\n') << endl << endl;
}
}
@@ -2727,7 +2728,7 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll)
t << escapeDependencyPath(specdir() + Option::dir_sep + "qmake.conf") << " ";
}
const ProStringList &included = escapeDependencyPaths(project->values("QMAKE_INTERNAL_INCLUDED_FILES"));
- t << included.join(" \\\n\t\t") << "\n\t"
+ t << included.join(QString(" \\\n\t\t")) << "\n\t"
<< qmake << endl;
for(int include = 0; include < included.size(); ++include) {
const ProString &i = included.at(include);
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index 9312f19418..c53393e268 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -241,13 +241,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\\\n\t\t" << (*objit);
}
if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
- t << escapeFilePaths(incrs_out).join(" \\\n\t\t") << endl;
+ t << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << endl;
} else if(!incrs_out.count()) {
t << endl;
} else {
src_incremental = true;
t << endl;
- t << "INCREMENTAL_OBJECTS = " << escapeFilePaths(incrs_out).join(" \\\n\t\t") << endl;
+ t << "INCREMENTAL_OBJECTS = "
+ << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << endl;
}
} else {
// Used all over the place in both deps and commands.
diff --git a/qmake/generators/win32/cesdkhandler.cpp b/qmake/generators/win32/cesdkhandler.cpp
deleted file mode 100644
index f45cbf74a9..0000000000
--- a/qmake/generators/win32/cesdkhandler.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "cesdkhandler.h"
-
-#include <qfile.h>
-#include <qfileinfo.h>
-#include <qdebug.h>
-#include <qxmlstream.h>
-#include <qsettings.h>
-#include <qtextstream.h>
-
-QT_BEGIN_NAMESPACE
-
-struct PropertyContainer
-{
- void clear() { name.clear(); value.clear(); properties.clear(); }
- QString name;
- QString value;
- QMap<QString, PropertyContainer> properties;
-};
-Q_DECLARE_TYPEINFO(PropertyContainer, Q_MOVABLE_TYPE);
-
-CeSdkInfo::CeSdkInfo() : m_major(0) , m_minor(0)
-{
-}
-
-CeSdkHandler::CeSdkHandler()
-{
-}
-
-struct ContainsPathKey
-{
- bool operator()(const QString &val) const
- {
- return !(val.endsWith(QLatin1String("MSBuildToolsPath"))
- || val.endsWith(QLatin1String("MSBuildToolsRoot")));
- }
-};
-
-struct ValueFromKey
-{
- explicit ValueFromKey(const QSettings *settings) : settings(settings) {}
- QString operator()(const QString &key) const
- {
- return settings->value(key).toString();
- }
-
- const QSettings *settings;
-};
-
-bool CeSdkHandler::parseMsBuildFile(QFile *file, CeSdkInfo *info)
-{
- bool result = file->open(QFile::ReadOnly | QFile::Text);
- const QString IncludePath = QStringLiteral("IncludePath");
- const QString LibraryPath = QStringLiteral("LibraryPath");
- const QString PreprocessorDefinitions = QStringLiteral("PreprocessorDefinitions");
- const QString SdkRootPathString = QStringLiteral("SdkRootPath");
- const QString ExecutablePath = QStringLiteral("ExecutablePath");
- enum ParserState{Not, Include, Lib, Define, BinDir, SdkRootPath};
- QString includePath;
- QString libraryPath;
- QString defines;
- QString binDirs;
- QString sdkRootPath;
- ParserState state = Not;
- if (result) {
- QXmlStreamReader xml(file);
- while (!xml.atEnd()) {
- if (xml.isStartElement()) {
- if (xml.name() == IncludePath)
- state = Include;
- else if (xml.name() == LibraryPath)
- state = Lib;
- else if (xml.name() == PreprocessorDefinitions)
- state = Define;
- else if (xml.name() == SdkRootPathString)
- state = SdkRootPath;
- else if (xml.name() == ExecutablePath)
- state = BinDir;
- else
- state = Not;
- } else if (xml.isEndElement()) {
- state = Not;
- } else if (xml.isCharacters()) {
- switch (state) {
- case Include:
- includePath += xml.text();
- break;
- case Lib:
- libraryPath += xml.text();
- break;
- case Define:
- defines += xml.text();
- break;
- case SdkRootPath:
- sdkRootPath = xml.text().toString();
- break;
- case BinDir:
- binDirs += xml.text();
- case(Not):
- break;
- }
- }
- xml.readNext();
- }
- }
- file->close();
- const bool success = result && !includePath.isEmpty() && !libraryPath.isEmpty() &&
- !defines.isEmpty() && !sdkRootPath.isEmpty();
- if (success) {
- const QString startPattern = QStringLiteral("$(Registry:");
- const int startIndex = sdkRootPath.indexOf(startPattern);
- const int endIndex = sdkRootPath.lastIndexOf(QLatin1Char(')'));
- const QString regString = sdkRootPath.mid(startIndex + startPattern.size(),
- endIndex - startIndex - startPattern.size());
- QSettings sdkRootPathRegistry(regString, QSettings::NativeFormat);
- const QString erg = sdkRootPathRegistry.value(QStringLiteral(".")).toString();
- const QString fullSdkRootPath = erg + sdkRootPath.mid(endIndex + 1);
- const QLatin1String rootString("$(SdkRootPath)");
-
- includePath = includePath.replace(rootString, fullSdkRootPath);
- libraryPath = libraryPath.replace(rootString, fullSdkRootPath);
- binDirs = binDirs.replace(rootString, fullSdkRootPath);
- info->m_include = includePath + ";$(INCLUDE)";
- info->m_lib = libraryPath;
- info->m_bin = binDirs;
- }
- return success;
-}
-
-QStringList CeSdkHandler::getMsBuildToolPaths() const
-{
- QSettings msbuildEntries("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\MSBuild\\ToolsVersions",
- QSettings::NativeFormat);
- const QStringList allKeys = msbuildEntries.allKeys();
- QStringList toolVersionKeys;
- toolVersionKeys.push_back(QStringLiteral("c:\\Program Files\\MSBuild\\"));
- std::remove_copy_if(allKeys.cbegin(), allKeys.cend(),
- std::back_inserter(toolVersionKeys), ContainsPathKey());
- QStringList toolVersionValues;
- std::transform(toolVersionKeys.constBegin(), toolVersionKeys.constEnd(),
- std::back_inserter(toolVersionValues),
- ValueFromKey(&msbuildEntries));
- return toolVersionValues;
-}
-
-QStringList CeSdkHandler::filterMsBuildToolPaths(const QStringList &paths) const
-{
- QStringList result;
- for (const QString &path : paths) {
- QDir dirVC110(path);
- if (path.endsWith(QLatin1String("bin")))
- dirVC110.cdUp();
- QDir dirVC120 = dirVC110;
- if (dirVC110.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V110\\Platforms")))
- result << dirVC110.absolutePath();
- if (dirVC120.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V120\\Platforms")))
- result << dirVC120.absolutePath();
- }
- return result;
-}
-
-bool CeSdkHandler::retrieveEnvironment(const QStringList &relativePaths,
- const QStringList &toolPaths,
- CeSdkInfo *info)
-{
- bool result = false;
- for (const QString &path : toolPaths) {
- const QDir dir(path);
- for (const QString &filePath : relativePaths) {
- QFile file(dir.absoluteFilePath(filePath));
- if (file.exists())
- result = parseMsBuildFile(&file, info) || result;
- }
- }
-
- return result;
-}
-
-void CeSdkHandler::retrieveWEC2013SDKs()
-{
- const QStringList toolPaths = getMsBuildToolPaths();
- const QStringList filteredToolPaths = filterMsBuildToolPaths(toolPaths);
- QSettings settings("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows CE Tools\\SDKs", QSettings::NativeFormat);
- const QStringList keys = settings.allKeys();
- for (const QString &key : keys) {
- if (key.contains(QLatin1String("SDKInformation")) || key.contains(QLatin1Char('.'))) {
- QFile sdkPropertyFile(settings.value(key).toString());
- if (!sdkPropertyFile.exists())
- continue;
- QFileInfo info(sdkPropertyFile);
- if (info.isDir()) {
- const QDir dir = info.absoluteFilePath();
- QFileInfo fInfo(dir.filePath(QLatin1String("Properties.xml")));
- if (fInfo.exists())
- sdkPropertyFile.setFileName(fInfo.absoluteFilePath());
- }
- if (!sdkPropertyFile.open(QFile::ReadOnly))
- continue;
- QXmlStreamReader xml(&sdkPropertyFile);
- QString currentElement;
- QString curName;
- PropertyContainer currentProperty;
- QVector<PropertyContainer> propStack;
- propStack.push_back(currentProperty);
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement()) {
- currentElement = xml.name().toString();
- if (currentElement == QLatin1String("Property")) {
- QXmlStreamAttributes attributes = xml.attributes();
- if (attributes.hasAttribute(QLatin1String("NAME")))
- curName = attributes.value(QLatin1String("NAME")).toString();
- Q_ASSERT(!curName.isEmpty());
- currentProperty.clear();
- currentProperty.name = curName;
- propStack.push_back(currentProperty);
- } else if (currentElement == QLatin1String("PropertyBag")) {
- QXmlStreamAttributes attributes = xml.attributes();
- if (attributes.hasAttribute(QLatin1String("NAME")))
- curName = attributes.value(QLatin1String("NAME")).toString();
- Q_ASSERT(!curName.isEmpty());
- currentProperty.clear();
- currentProperty.name = curName;
- propStack.push_back(currentProperty);
- }
- } else if (xml.isEndElement()) {
- currentElement = xml.name().toString();
- PropertyContainer self = propStack.takeLast();
- if (currentElement != QLatin1String("Root")) {
- PropertyContainer &last = propStack.last();
- last.properties[self.name] = self;
- } else {
- currentProperty = self;
- }
- } else if (xml.isCharacters()) {
- PropertyContainer &self = propStack.last();
- self.value = xml.text().toString();
- }
- }
-
- if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
- qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
- return;
- }
- CeSdkInfo currentSdk;
- const PropertyContainer &cpuInfo = currentProperty.properties.value(QLatin1String("CPU info"));
- if (cpuInfo.properties.isEmpty())
- continue;
- const PropertyContainer &cpuInfoVal = cpuInfo.properties.first().properties.value(QLatin1String("CpuName"));
- if (cpuInfoVal.name != QLatin1String("CpuName"))
- continue;
- const QString SDKName = QStringLiteral("SDK name");
- currentSdk.m_name = currentProperty.properties.value(SDKName).value+
- QStringLiteral(" (") + cpuInfoVal.value + ")";
- currentSdk.m_major = currentProperty.properties.value(QLatin1String("OSMajor")).value.toInt();
- currentSdk.m_minor = currentProperty.properties.value(QLatin1String("OSMinor")).value.toInt();
- retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files110")).value.split(';'),
- filteredToolPaths, &currentSdk);
- retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files120")).value.split(';'),
- filteredToolPaths, &currentSdk);
- if (!currentSdk.m_include.isEmpty())
- m_list.append(currentSdk);
- }
- }
-}
-
-void CeSdkHandler::retrieveWEC6n7SDKs()
-{
- // look at the file at %VCInstallDir%/vcpackages/WCE.VCPlatform.config
- // and scan through all installed sdks...
- m_vcInstallDir = QString::fromLatin1(qgetenv("VCInstallDir"));
- if (m_vcInstallDir.isEmpty())
- return;
-
- QDir vStudioDir(m_vcInstallDir);
- if (!vStudioDir.cd(QLatin1String("vcpackages")))
- return;
-
- QFile configFile(vStudioDir.absoluteFilePath(QLatin1String("WCE.VCPlatform.config")));
- if (!configFile.open(QIODevice::ReadOnly))
- return;
-
- QString currentElement;
- CeSdkInfo currentItem;
- QXmlStreamReader xml(&configFile);
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement()) {
- currentElement = xml.name().toString();
- if (currentElement == QLatin1String("Platform")) {
- currentItem = CeSdkInfo();
- } else if (currentElement == QLatin1String("Directories")) {
- QXmlStreamAttributes attr = xml.attributes();
- currentItem.m_include = fixPaths(attr.value(QLatin1String("Include")).toString());
- currentItem.m_lib = fixPaths(attr.value(QLatin1String("Library")).toString());
- currentItem.m_bin = fixPaths(attr.value(QLatin1String("Path")).toString());
- }
- } else if (xml.isEndElement()) {
- if (xml.name().toString() == QLatin1String("Platform"))
- m_list.append(currentItem);
- } else if (xml.isCharacters() && !xml.isWhitespace()) {
- if (currentElement == QLatin1String("PlatformName"))
- currentItem.m_name = xml.text().toString();
- else if (currentElement == QLatin1String("OSMajorVersion"))
- currentItem.m_major = xml.text().toString().toInt();
- else if (currentElement == QLatin1String("OSMinorVersion"))
- currentItem.m_minor = xml.text().toString().toInt();
- }
- }
-
- if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
- qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
- return;
- }
-}
-
-bool CeSdkHandler::retrieveAvailableSDKs()
-{
- m_list.clear();
- retrieveWEC2013SDKs();
- retrieveWEC6n7SDKs();
- return !m_list.empty();
-}
-
-QString CeSdkHandler::fixPaths(const QString &path) const
-{
- QRegExp searchStr(QLatin1String("(\\$\\(\\w+\\))"));
- QString fixedString = path;
- for (int index = fixedString.indexOf(searchStr, 0);
- index >= 0;
- index = fixedString.indexOf(searchStr, index)) {
- const QString capture = searchStr.cap(0);
- fixedString.replace(index, capture.length(), capture.toUpper());
- index += capture.length(); // don't count the zero terminator
- fixedString.insert(index, '\\'); // the configuration file lacks a directory separator for env vars
- ++index;
- }
- return fixedString;
-}
-
-QT_END_NAMESPACE
diff --git a/qmake/generators/win32/cesdkhandler.h b/qmake/generators/win32/cesdkhandler.h
deleted file mode 100644
index 3bb8d2adcb..0000000000
--- a/qmake/generators/win32/cesdkhandler.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef CE_SDK_HANDLER_INCL
-#define CE_SDK_HANDLER_INCL
-
-#include <qstringlist.h>
-#include <qdir.h>
-
-QT_BEGIN_NAMESPACE
-
-class CeSdkInfo
-{
-public:
- CeSdkInfo();
- inline QString name() const { return m_name; }
- inline QString binPath() const { return m_bin; }
- inline QString includePath() const { return m_include; }
- inline QString libPath() const { return m_lib; }
- inline bool isValid() const;
- inline int majorVersion() const { return m_major; }
- inline int minorVersion() const { return m_minor; }
- inline bool isSupported() const { return m_major >= 5; }
-private:
- friend class CeSdkHandler;
- QString m_name;
- QString m_bin;
- QString m_include;
- QString m_lib;
- int m_major;
- int m_minor;
-};
-
-bool CeSdkInfo::isValid() const
-{
- return !m_name.isEmpty() &&
- !m_bin.isEmpty() &&
- !m_include.isEmpty() &&
- !m_lib.isEmpty();
-}
-
-class CeSdkHandler
-{
-public:
- CeSdkHandler();
- bool retrieveAvailableSDKs();
- inline QList<CeSdkInfo> listAll() const { return m_list; }
-private:
- void retrieveWEC6n7SDKs();
- void retrieveWEC2013SDKs();
- inline QString fixPaths(const QString &path) const;
- QStringList getMsBuildToolPaths() const;
- QStringList filterMsBuildToolPaths(const QStringList &paths) const;
- bool parseMsBuildFile(QFile *file, CeSdkInfo *info);
- bool retrieveEnvironment(const QStringList &relativePaths,
- const QStringList &toolPaths,
- CeSdkInfo *info);
- QList<CeSdkInfo> m_list;
- QString m_vcInstallDir;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index d8ac80f99d..9e1af05414 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -28,7 +28,6 @@
#include "msvc_nmake.h"
#include "option.h"
-#include "cesdkhandler.h"
#include <qregexp.h>
#include <qdir.h>
@@ -72,38 +71,7 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
return MakefileGenerator::writeStubMakefile(t);
#endif
if (!project->isHostBuild()) {
- const ProValueMap &variables = project->variables();
- if (project->isActiveConfig("wince")) {
- CeSdkHandler sdkhandler;
- sdkhandler.retrieveAvailableSDKs();
- const QString sdkName = variables["CE_SDK"].join(' ')
- + " (" + variables["CE_ARCH"].join(' ') + ")";
- const QList<CeSdkInfo> sdkList = sdkhandler.listAll();
- CeSdkInfo sdk;
- for (const CeSdkInfo &info : sdkList) {
- if (info.name().compare(sdkName, Qt::CaseInsensitive ) == 0) {
- sdk = info;
- break;
- }
- }
- if (sdk.isValid()) {
- t << "\nINCLUDE = " << sdk.includePath();
- t << "\nLIB = " << sdk.libPath();
- t << "\nPATH = " << sdk.binPath() << "\n";
- } else {
- QStringList sdkStringList;
- sdkStringList.reserve(sdkList.size());
- for (const CeSdkInfo &info : sdkList)
- sdkStringList << info.name();
-
- fprintf(stderr, "Failed to find Windows CE SDK matching %s, found: %s\n"
- "SDK needs to be specified in mkspec (using: %s/qmake.conf)\n"
- "SDK name needs to match the following format: CE_SDK (CE_ARCH)\n",
- qPrintable(sdkName), qPrintable(sdkStringList.join(", ")),
- qPrintable(variables["QMAKESPEC"].first().toQString()));
- return false;
- }
- } else if (project->isActiveConfig(QStringLiteral("winrt"))) {
+ if (project->isActiveConfig(QStringLiteral("winrt"))) {
QString arch = project->first("VCPROJ_ARCH").toQString().toLower();
QString compiler;
QString compilerArch;
@@ -614,12 +582,6 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
writeLinkCommand(t);
}
}
- QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE");
- bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") &&
- !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
- if(useSignature) {
- t << "\n\tsigntool sign /F " << escapeFilePath(signature) << " $(DESTDIR_TARGET)";
- }
if(!project->isEmpty("QMAKE_POST_LINK")) {
t << "\n\t" << var("QMAKE_POST_LINK");
}
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index d55e5bacf2..51cf5abdd4 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -490,7 +490,8 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
// Check if all requirements are fulfilled
if (!tmp_proj.isEmpty("QMAKE_FAILED_REQUIREMENTS")) {
fprintf(stderr, "Project file(%s) not added to Solution because all requirements not met:\n\t%s\n",
- fn.toLatin1().constData(), tmp_proj.values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData());
+ fn.toLatin1().constData(),
+ tmp_proj.values("QMAKE_FAILED_REQUIREMENTS").join(' ').toLatin1().constData());
qmake_setpwd(oldpwd);
Option::output_dir = oldoutpwd;
continue;
@@ -700,11 +701,6 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
QString slnConf = _slnSolutionConf;
if (!project->isEmpty("VCPROJ_ARCH")) {
slnConf.replace(QLatin1String("|Win32"), "|" + project->first("VCPROJ_ARCH"));
- } else if (!project->isEmpty("CE_PLATFORMNAME")) {
- slnConf.replace(QLatin1String("|Win32"), "|" + project->first("CE_PLATFORMNAME"));
- } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) {
- QString slnPlatform = QString("|") + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
- slnConf.replace(QLatin1String("|Win32"), slnPlatform);
} else if (is64Bit) {
slnConf.replace(QLatin1String("|Win32"), QLatin1String("|x64"));
}
@@ -719,10 +715,6 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
QString xplatform = platform;
if (!project->isEmpty("VCPROJ_ARCH")) {
xplatform = project->first("VCPROJ_ARCH").toQString();
- } else if (!project->isEmpty("CE_PLATFORMNAME")) {
- xplatform = project->first("CE_PLATFORMNAME").toQString();
- } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) {
- xplatform = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
}
if (!project->isHostBuild())
platform = xplatform;
@@ -980,12 +972,8 @@ void VcprojGenerator::initProject()
vcProject.Keyword = project->first("VCPROJ_KEYWORD").toQString();
if (!project->isEmpty("VCPROJ_ARCH")) {
vcProject.PlatformName = project->first("VCPROJ_ARCH").toQString();
- } else if (!project->isEmpty("CE_PLATFORMNAME")) {
- vcProject.PlatformName = project->first("CE_PLATFORMNAME").toQString();
- } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
+ } else if (project->isHostBuild()) {
vcProject.PlatformName = (is64Bit ? "x64" : "Win32");
- } else {
- vcProject.PlatformName = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
}
vcProject.SdkVersion = project->first("WINSDK_VER").toQString();
// These are not used by Qt, but may be used by customers
@@ -1066,12 +1054,8 @@ void VcprojGenerator::initConfiguration()
conf.ConfigurationName = conf.Name;
if (!project->isEmpty("VCPROJ_ARCH")) {
conf.Name += "|" + project->first("VCPROJ_ARCH");
- } else if (!project->isEmpty("CE_PLATFORMNAME")) {
- conf.Name += "|" + project->first("CE_PLATFORMNAME");
- } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
+ } else if (project->isHostBuild()) {
conf.Name += (is64Bit ? "|x64" : "|Win32");
- } else {
- conf.Name += "|" + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
}
conf.ATLMinimizesCRunTimeLibraryUsage = (project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True);
conf.BuildBrowserInformation = triState(temp.isEmpty() ? (short)unset : temp.toShort());
@@ -1094,8 +1078,7 @@ void VcprojGenerator::initConfiguration()
initPreBuildEventTools();
initPostBuildEventTools();
// Only deploy for CE and WinRT projects
- if ((!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
- || conf.WinRT)
+ if (!project->isHostBuild() || conf.WinRT)
initDeploymentTool();
initWinDeployQtTool();
initPreLinkEventTools();
@@ -1243,16 +1226,6 @@ void VcprojGenerator::initPostBuildEventTools()
conf.postBuild.Description = cmdline.join(QLatin1String("\r\n"));
conf.postBuild.ExcludedFromBuild = _False;
}
-
- QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE");
- bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") &&
- !project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
- if (useSignature) {
- conf.postBuild.CommandLine.prepend(
- QLatin1String("signtool sign /F ") + escapeFilePath(signature) + QLatin1String(" \"$(TargetPath)\""));
- conf.postBuild.ExcludedFromBuild = _False;
- }
-
if (!project->values("MSVCPROJ_COPY_DLL").isEmpty()) {
conf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC");
conf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL");
@@ -1346,45 +1319,6 @@ void VcprojGenerator::initDeploymentTool()
}
}
- if (!conf.WinRT) {
- // C-runtime deployment
- QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1Char(' '));
- if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) {
- QString runtimeVersion = QLatin1String("msvcr");
- ProString mkspec = project->first("QMAKESPEC");
-
- if (!mkspec.isEmpty()) {
- if (mkspec.endsWith("2008"))
- runtimeVersion.append("90");
- else
- runtimeVersion.append("80");
- if (project->isActiveConfig("debug"))
- runtimeVersion.append("d");
- runtimeVersion.append(".dll");
-
- if (runtime == "yes") {
- // Auto-find C-runtime
- QString vcInstallDir = qgetenv("VCINSTALLDIR");
- if (!vcInstallDir.isEmpty()) {
- vcInstallDir += "\\ce\\dll\\";
- vcInstallDir += project->values("CE_ARCH").join(QLatin1Char(' '));
- if (!QFileInfo::exists(vcInstallDir + QDir::separator() + runtimeVersion))
- runtime.clear();
- else
- runtime = vcInstallDir;
- }
- }
- }
-
- if (!runtime.isEmpty() && runtime != QLatin1String("yes")) {
- conf.deployment.AdditionalFiles += runtimeVersion
- + "|" + QDir::toNativeSeparators(runtime)
- + "|" + targetPath
- + "|0;";
- }
- }
- }
-
for (const ProString &item : project->values("INSTALLS")) {
// get item.path
QString devicePath = project->first(ProKey(item + ".path")).toQString();
diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp
index 5f923744be..66db190bc1 100644
--- a/qmake/library/proitems.cpp
+++ b/qmake/library/proitems.cpp
@@ -365,6 +365,11 @@ static QString ProStringList_join(const ProStringList &this_, const QChar *sep,
return res;
}
+QString ProStringList::join(const ProString &sep) const
+{
+ return ProStringList_join(*this, sep.constData(), sep.size());
+}
+
QString ProStringList::join(const QString &sep) const
{
return ProStringList_join(*this, sep.constData(), sep.size());
@@ -453,6 +458,14 @@ bool ProStringList::contains(const ProString &str, Qt::CaseSensitivity cs) const
return false;
}
+bool ProStringList::contains(const QStringRef &str, Qt::CaseSensitivity cs) const
+{
+ for (int i = 0; i < size(); i++)
+ if (!at(i).toQStringRef().compare(str, cs))
+ return true;
+ return false;
+}
+
bool ProStringList::contains(const char *str, Qt::CaseSensitivity cs) const
{
for (int i = 0; i < size(); i++)
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index dcff970600..16dd9386c8 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -100,6 +100,7 @@ public:
bool operator!=(const QString &other) const { return !(*this == other); }
bool operator!=(QLatin1String other) const { return !(*this == other); }
bool operator!=(const char *other) const { return !(*this == other); }
+ bool operator<(const ProString &other) const { return toQStringRef() < other.toQStringRef(); }
bool isNull() const { return m_string.isNull(); }
bool isEmpty() const { return !m_length; }
int length() const { return m_length; }
@@ -233,6 +234,7 @@ public:
int length() const { return size(); }
+ QString join(const ProString &sep) const;
QString join(const QString &sep) const;
QString join(QChar sep) const;
@@ -246,6 +248,7 @@ public:
void removeDuplicates();
bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return contains(ProString(str), cs); }
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 80569e503a..6f93b655b4 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -80,9 +80,10 @@ QT_BEGIN_NAMESPACE
#define fL1S(s) QString::fromLatin1(s)
enum ExpandFunc {
- E_INVALID = 0, E_MEMBER, E_FIRST, E_LAST, E_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST,
- E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
- E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
+ E_INVALID = 0, E_MEMBER, E_STR_MEMBER, E_FIRST, E_TAKE_FIRST, E_LAST, E_TAKE_LAST,
+ E_SIZE, E_STR_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_FORMAT_NUMBER,
+ E_NUM_ADD, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
+ E_FIND, E_SYSTEM, E_UNIQUE, E_SORTED, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
@@ -104,15 +105,20 @@ void QMakeEvaluator::initFunctionStatics()
const ExpandFunc func;
} expandInits[] = {
{ "member", E_MEMBER },
+ { "str_member", E_STR_MEMBER },
{ "first", E_FIRST },
+ { "take_first", E_TAKE_FIRST },
{ "last", E_LAST },
+ { "take_last", E_TAKE_LAST },
{ "size", E_SIZE },
+ { "str_size", E_STR_SIZE },
{ "cat", E_CAT },
{ "fromfile", E_FROMFILE },
{ "eval", E_EVAL },
{ "list", E_LIST },
{ "sprintf", E_SPRINTF },
{ "format_number", E_FORMAT_NUMBER },
+ { "num_add", E_NUM_ADD },
{ "join", E_JOIN },
{ "split", E_SPLIT },
{ "basename", E_BASENAME },
@@ -121,6 +127,7 @@ void QMakeEvaluator::initFunctionStatics()
{ "find", E_FIND },
{ "system", E_SYSTEM },
{ "unique", E_UNIQUE },
+ { "sorted", E_SORTED },
{ "reverse", E_REVERSE },
{ "quote", E_QUOTE },
{ "escape_expand", E_ESCAPE_EXPAND },
@@ -197,6 +204,49 @@ static bool isTrue(const ProString &str)
return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt();
}
+bool
+QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringList &args,
+ int *start, int *end)
+{
+ *start = 0, *end = 0;
+ if (args.count() >= 2) {
+ bool ok = true;
+ const ProString &start_str = args.at(1);
+ *start = start_str.toInt(&ok);
+ if (!ok) {
+ if (args.count() == 2) {
+ int dotdot = start_str.indexOf(statics.strDotDot);
+ if (dotdot != -1) {
+ *start = start_str.left(dotdot).toInt(&ok);
+ if (ok)
+ *end = start_str.mid(dotdot+2).toInt(&ok);
+ }
+ }
+ if (!ok) {
+ evalError(fL1S("%1() argument 2 (start) '%2' invalid.")
+ .arg(func.toQString(m_tmp1), start_str.toQString(m_tmp2)));
+ return false;
+ }
+ } else {
+ *end = *start;
+ if (args.count() == 3)
+ *end = args.at(2).toInt(&ok);
+ if (!ok) {
+ evalError(fL1S("%1() argument 3 (end) '%2' invalid.")
+ .arg(func.toQString(m_tmp1), args.at(2).toQString(m_tmp2)));
+ return false;
+ }
+ }
+ }
+ if (*start < 0)
+ *start += srclen;
+ if (*end < 0)
+ *end += srclen;
+ if (*start < 0 || *start >= srclen || *end < 0 || *end >= srclen)
+ return false;
+ return true;
+}
+
#if defined(Q_OS_WIN) && defined(PROEVALUATOR_FULL)
static QString windowsErrorCode()
{
@@ -532,31 +582,30 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
bool leftalign = false;
enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
if (args.count() >= 2) {
- const auto opts = split_value_list(args.at(1).toQString(m_tmp2));
+ const auto opts = split_value_list(args.at(1).toQStringRef());
for (const ProString &opt : opts) {
- opt.toQString(m_tmp3);
- if (m_tmp3.startsWith(QLatin1String("ibase="))) {
- ibase = m_tmp3.mid(6).toInt();
- } else if (m_tmp3.startsWith(QLatin1String("obase="))) {
- obase = m_tmp3.mid(6).toInt();
- } else if (m_tmp3.startsWith(QLatin1String("width="))) {
- width = m_tmp3.mid(6).toInt();
- } else if (m_tmp3 == QLatin1String("zeropad")) {
+ if (opt.startsWith(QLatin1String("ibase="))) {
+ ibase = opt.mid(6).toInt();
+ } else if (opt.startsWith(QLatin1String("obase="))) {
+ obase = opt.mid(6).toInt();
+ } else if (opt.startsWith(QLatin1String("width="))) {
+ width = opt.mid(6).toInt();
+ } else if (opt == QLatin1String("zeropad")) {
zeropad = true;
- } else if (m_tmp3 == QLatin1String("padsign")) {
+ } else if (opt == QLatin1String("padsign")) {
sign = PadSign;
- } else if (m_tmp3 == QLatin1String("alwayssign")) {
+ } else if (opt == QLatin1String("alwayssign")) {
sign = AlwaysSign;
- } else if (m_tmp3 == QLatin1String("leftalign")) {
+ } else if (opt == QLatin1String("leftalign")) {
leftalign = true;
} else {
- evalError(fL1S("format_number(): invalid format option %1.").arg(m_tmp3));
+ evalError(fL1S("format_number(): invalid format option %1.")
+ .arg(opt.toQString(m_tmp3)));
goto formfail;
}
}
}
- args.at(0).toQString(m_tmp3);
- if (m_tmp3.contains(QLatin1Char('.'))) {
+ if (args.at(0).contains(QLatin1Char('.'))) {
evalError(fL1S("format_number(): floats are currently not supported."));
break;
}
@@ -564,7 +613,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
qlonglong num = args.at(0).toLongLong(&ok, ibase);
if (!ok) {
evalError(fL1S("format_number(): malformed number %2 for base %1.")
- .arg(ibase).arg(m_tmp3));
+ .arg(ibase).arg(args.at(0).toQString(m_tmp3)));
break;
}
QString outstr;
@@ -592,14 +641,36 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
}
formfail:
break;
+ case E_NUM_ADD:
+ if (args.count() < 1 || args.at(0).isEmpty()) {
+ evalError(fL1S("num_add(num, ...) requires at least one argument."));
+ } else {
+ qlonglong sum = 0;
+ for (const ProString &arg : qAsConst(args)) {
+ if (arg.contains(QLatin1Char('.'))) {
+ evalError(fL1S("num_add(): floats are currently not supported."));
+ goto nafail;
+ }
+ bool ok;
+ qlonglong num = arg.toLongLong(&ok);
+ if (!ok) {
+ evalError(fL1S("num_add(): malformed number %1.")
+ .arg(arg.toQString(m_tmp3)));
+ goto nafail;
+ }
+ sum += num;
+ }
+ ret += ProString(QString::number(sum));
+ }
+ nafail:
+ break;
case E_JOIN: {
if (args.count() < 1 || args.count() > 4) {
evalError(fL1S("join(var, glue, before, after) requires one to four arguments."));
} else {
- QString glue;
- ProString before, after;
+ ProString glue, before, after;
if (args.count() >= 2)
- glue = args.at(1).toQString(m_tmp1);
+ glue = args.at(1);
if (args.count() >= 3)
before = args[2];
if (args.count() == 4)
@@ -634,47 +705,37 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
if (args.count() < 1 || args.count() > 3) {
evalError(fL1S("member(var, start, end) requires one to three arguments."));
} else {
- bool ok = true;
- const ProStringList &var = values(map(args.at(0)));
- int start = 0, end = 0;
- if (args.count() >= 2) {
- const ProString &start_str = args.at(1);
- start = start_str.toInt(&ok);
- if (!ok) {
- if (args.count() == 2) {
- int dotdot = start_str.indexOf(statics.strDotDot);
- if (dotdot != -1) {
- start = start_str.left(dotdot).toInt(&ok);
- if (ok)
- end = start_str.mid(dotdot+2).toInt(&ok);
- }
- }
- if (!ok)
- evalError(fL1S("member() argument 2 (start) '%2' invalid.")
- .arg(start_str.toQString(m_tmp1)));
+ const ProStringList &src = values(map(args.at(0)));
+ int start, end;
+ if (getMemberArgs(func, src.size(), args, &start, &end)) {
+ ret.reserve(qAbs(end - start) + 1);
+ if (start < end) {
+ for (int i = start; i <= end && src.size() >= i; i++)
+ ret += src.at(i);
} else {
- end = start;
- if (args.count() == 3)
- end = args.at(2).toInt(&ok);
- if (!ok)
- evalError(fL1S("member() argument 3 (end) '%2' invalid.")
- .arg(args.at(2).toQString(m_tmp1)));
+ for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
+ ret += src.at(i);
}
}
- if (ok) {
- if (start < 0)
- start += var.count();
- if (end < 0)
- end += var.count();
- if (start < 0 || start >= var.count() || end < 0 || end >= var.count()) {
- //nothing
- } else if (start < end) {
- for (int i = start; i <= end && var.count() >= i; i++)
- ret.append(var[i]);
+ }
+ break;
+ case E_STR_MEMBER:
+ if (args.count() < 1 || args.count() > 3) {
+ evalError(fL1S("str_member(str, start, end) requires one to three arguments."));
+ } else {
+ const ProString &src = args.at(0);
+ int start, end;
+ if (getMemberArgs(func, src.size(), args, &start, &end)) {
+ QString res;
+ res.reserve(qAbs(end - start) + 1);
+ if (start < end) {
+ for (int i = start; i <= end && src.size() >= i; i++)
+ res += src.at(i);
} else {
- for (int i = start; i >= end && var.count() >= i && i >= 0; i--)
- ret += var[i];
+ for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
+ res += src.at(i);
}
+ ret += ProString(res);
}
}
break;
@@ -692,12 +753,32 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
}
}
break;
+ case E_TAKE_FIRST:
+ case E_TAKE_LAST:
+ if (args.count() != 1) {
+ evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1)));
+ } else {
+ ProStringList &var = valuesRef(map(args.at(0)));
+ if (!var.isEmpty()) {
+ if (func_t == E_TAKE_FIRST)
+ ret.append(var.takeFirst());
+ else
+ ret.append(var.takeLast());
+ }
+ }
+ break;
case E_SIZE:
if (args.count() != 1)
evalError(fL1S("size(var) requires one argument."));
else
ret.append(ProString(QString::number(values(map(args.at(0))).size())));
break;
+ case E_STR_SIZE:
+ if (args.count() != 1)
+ evalError(fL1S("str_size(str) requires one argument."));
+ else
+ ret.append(ProString(QString::number(args.at(0).size())));
+ break;
case E_CAT:
if (args.count() < 1 || args.count() > 2) {
evalError(fL1S("cat(file, singleline=true) requires one or two arguments."));
@@ -708,12 +789,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
bool lines = false;
bool singleLine = true;
if (args.count() > 1) {
- args.at(1).toQString(m_tmp2);
- if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive))
+ if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
singleLine = false;
- else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive))
+ else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
blob = true;
- else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive))
+ else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
lines = true;
}
@@ -727,7 +807,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
if (lines) {
ret += ProString(stream.readLine());
} else {
- ret += split_value_list(stream.readLine().trimmed());
+ const QString &line = stream.readLine();
+ ret += split_value_list(QStringRef(&line).trimmed());
if (!singleLine)
ret += ProString("\n");
}
@@ -759,7 +840,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
ret = ProStringList(ProString(tmp));
ProStringList lst;
for (const ProString &arg : args)
- lst += split_value_list(arg.toQString(m_tmp1), arg.sourceFile()); // Relies on deep copy
+ lst += split_value_list(arg.toQStringRef(), arg.sourceFile()); // Relies on deep copy
m_valuemapStack.top()[ret.at(0).toKey()] = lst;
break; }
case E_FIND:
@@ -785,12 +866,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
bool lines = false;
bool singleLine = true;
if (args.count() > 1) {
- args.at(1).toQString(m_tmp2);
- if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive))
+ if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
singleLine = false;
- else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive))
+ else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
blob = true;
- else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive))
+ else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
lines = true;
}
QByteArray bytes = getCommandOutput(args.at(0).toQString(m_tmp2));
@@ -806,7 +886,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
output.replace(QLatin1Char('\t'), QLatin1Char(' '));
if (singleLine)
output.replace(QLatin1Char('\n'), QLatin1Char(' '));
- ret += split_value_list(output);
+ ret += split_value_list(QStringRef(&output));
}
}
}
@@ -820,6 +900,14 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
ret.removeDuplicates();
}
break;
+ case E_SORTED:
+ if (args.count() != 1) {
+ evalError(fL1S("sorted(var) requires one argument."));
+ } else {
+ ret = values(map(args.at(0)));
+ std::sort(ret.begin(), ret.end());
+ }
+ break;
case E_REVERSE:
if (args.count() != 1) {
evalError(fL1S("reverse(var) requires one argument."));
@@ -955,7 +1043,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
QFile qfile;
if (qfile.open(stdin, QIODevice::ReadOnly)) {
QTextStream t(&qfile);
- ret = split_value_list(t.readLine());
+ const QString &line = t.readLine();
+ ret = split_value_list(QStringRef(&line));
}
}
break; }
@@ -989,7 +1078,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
populateDeps(orgList, prefix,
args.count() < 3 ? ProStringList(ProString(".depends"))
- : split_value_list(args.at(2).toQString(m_tmp2)),
+ : split_value_list(args.at(2).toQStringRef()),
priosfx, dependencies, dependees, rootSet);
while (!rootSet.isEmpty()) {
QMultiMap<int, ProString>::iterator it = rootSet.begin();
@@ -1211,7 +1300,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse; // Another qmake breakage
case T_EVAL: {
VisitReturn ret = ReturnFalse;
- ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
+ QString contents = args.join(statics.field_sep);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
m_current.pro->fileName(), m_current.line);
if (m_cumulative || pro->isOk()) {
m_locationStack.push(m_current);
@@ -1227,7 +1317,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
evalError(fL1S("if(condition) requires one argument."));
return ReturnFalse;
}
- return returnBool(evaluateConditional(args.at(0).toQString(),
+ return returnBool(evaluateConditional(args.at(0).toQStringRef(),
m_current.pro->fileName(), m_current.line));
}
case T_CONFIG: {
@@ -1236,7 +1326,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
}
if (args.count() == 1)
- return returnBool(isActiveConfig(args.at(0).toQString(m_tmp2)));
+ return returnBool(isActiveConfig(args.at(0).toQStringRef()));
const QStringList &mutuals = args.at(1).toQString(m_tmp2).split(QLatin1Char('|'));
const ProStringList &configs = values(statics.strCONFIG);
@@ -1319,8 +1409,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
.arg(function.toQString(m_tmp1)));
return ReturnFalse;
}
- const QString &rhs(args.at(1).toQString(m_tmp1)),
- &lhs(values(map(args.at(0))).join(statics.field_sep));
+ const ProString &rhs = args.at(1);
+ const QString &lhs = values(map(args.at(0))).join(statics.field_sep);
bool ok;
int rhs_int = rhs.toInt(&ok);
if (ok) { // do integer compare
@@ -1332,8 +1422,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
}
if (func_t == T_GREATERTHAN)
- return returnBool(lhs > rhs);
- return returnBool(lhs < rhs);
+ return returnBool(lhs > rhs.toQStringRef());
+ return returnBool(lhs < rhs.toQStringRef());
}
case T_EQUALS:
if (args.count() != 2) {
@@ -1569,7 +1659,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (!vals.isEmpty())
contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n');
if (args.count() >= 3) {
- const auto opts = split_value_list(args.at(2).toQString(m_tmp2));
+ const auto opts = split_value_list(args.at(2).toQStringRef());
for (const ProString &opt : opts) {
opt.toQString(m_tmp3);
if (m_tmp3 == QLatin1String("append")) {
@@ -1642,7 +1732,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
ProKey srcvar;
if (args.count() >= 2) {
- const auto opts = split_value_list(args.at(1).toQString(m_tmp2));
+ const auto opts = split_value_list(args.at(1).toQStringRef());
for (const ProString &opt : opts) {
opt.toQString(m_tmp3);
if (m_tmp3 == QLatin1String("transient")) {
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index d7fe14c02f..b0def45447 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -270,7 +270,7 @@ void QMakeEvaluator::skipHashStr(const ushort *&tokPtr)
// FIXME: this should not build new strings for direct sections.
// Note that the E_SPRINTF and E_LIST implementations rely on the deep copy.
-ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFile *source)
+ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, const ProFile *source)
{
QString build;
ProStringList ret;
@@ -624,7 +624,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
evalError(fL1S("Conditional must expand to exactly one word."));
okey = false;
} else {
- okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true);
+ okey = isActiveConfig(curr.at(0).toQStringRef(), true);
traceMsg("condition %s is %s", dbgStr(curr.at(0)), dbgBool(okey));
okey ^= invert;
}
@@ -1277,7 +1277,7 @@ void QMakeEvaluator::setupProject()
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
{
if (!cmds.isEmpty()) {
- ProFile *pro = m_parser->parsedProBlock(cmds, where, -1);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), where, -1);
if (pro->isOk()) {
m_locationStack.push(m_current);
visitProBlock(pro, pro->tokPtr());
@@ -1571,7 +1571,7 @@ QString QMakeEvaluator::currentDirectory() const
return QString();
}
-bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex)
+bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex)
{
// magic types for easy flipping
if (config == statics.strtrue)
@@ -1583,7 +1583,7 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex)
return m_hostBuild;
if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) {
- QString cfg = config;
+ QString cfg = config.toString();
cfg.detach(); // Keep m_tmp out of QRegExp's cache
QRegExp re(cfg, Qt::CaseSensitive, QRegExp::Wildcard);
@@ -1605,7 +1605,7 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex)
return true;
// CONFIG variable
- if (values(statics.strCONFIG).contains(ProString(config)))
+ if (values(statics.strCONFIG).contains(config))
return true;
}
@@ -1760,7 +1760,7 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
return ProStringList();
}
-bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line)
+bool QMakeEvaluator::evaluateConditional(const QStringRef &cond, const QString &where, int line)
{
bool ret = false;
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
@@ -1778,7 +1778,7 @@ void QMakeEvaluator::checkRequirements(const ProStringList &deps)
{
ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS"));
for (const ProString &dep : deps)
- if (!evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line))
+ if (!evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line))
failed << dep;
}
#endif
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 5477d82f26..7b911e7911 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -176,7 +176,7 @@ public:
void setTemplate();
- ProStringList split_value_list(const QString &vals, const ProFile *source = 0);
+ ProStringList split_value_list(const QStringRef &vals, const ProFile *source = 0);
ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
@@ -216,7 +216,7 @@ public:
ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args);
VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
- bool evaluateConditional(const QString &cond, const QString &where, int line = -1);
+ bool evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
#ifdef PROEVALUATOR_FULL
void checkRequirements(const ProStringList &deps);
#endif
@@ -224,7 +224,7 @@ public:
void updateMkspecPaths();
void updateFeaturePaths();
- bool isActiveConfig(const QString &config, bool regex = false);
+ bool isActiveConfig(const QStringRef &config, bool regex = false);
void populateDeps(
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
@@ -232,6 +232,9 @@ public:
QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
QMultiMap<int, ProString> &rootSet) const;
+ bool getMemberArgs(const ProKey &name, int srclen, const ProStringList &args,
+ int *start, int *end);
+
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
bool exe, const QString &contents);
#ifndef QT_BOOTSTRAPPED
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
index 6a648e9ecf..f90ad905ee 100644
--- a/qmake/library/qmakeglobals.cpp
+++ b/qmake/library/qmakeglobals.cpp
@@ -134,6 +134,11 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
break;
default:
if (arg.startsWith(QLatin1Char('-'))) {
+ if (arg == QLatin1String("--")) {
+ state.extraargs = args.mid(*pos + 1);
+ *pos = args.size();
+ return ArgumentsOk;
+ }
if (arg == QLatin1String("-after"))
state.after = true;
else if (arg == QLatin1String("-config"))
@@ -179,6 +184,12 @@ void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
{
if (!state.preconfigs.isEmpty())
state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(QLatin1Char(' ')));
+ if (!state.extraargs.isEmpty()) {
+ QString extra = fL1S("QMAKE_EXTRA_ARGS =");
+ for (const QString &ea : qAsConst(state.extraargs))
+ extra += QLatin1Char(' ') + QMakeEvaluator::quoteValue(ProString(ea));
+ state.precmds << extra;
+ }
precmds = state.precmds.join(QLatin1Char('\n'));
if (!state.postconfigs.isEmpty())
state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(QLatin1Char(' ')));
diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h
index 79237e6ebe..96c39fa168 100644
--- a/qmake/library/qmakeglobals.h
+++ b/qmake/library/qmakeglobals.h
@@ -85,7 +85,7 @@ class QMAKE_EXPORT QMakeCmdLineParserState
public:
QMakeCmdLineParserState(const QString &_pwd) : pwd(_pwd), after(false) {}
QString pwd;
- QStringList precmds, preconfigs, postcmds, postconfigs;
+ QStringList precmds, preconfigs, postcmds, postconfigs, extraargs;
bool after;
void flush() { after = false; }
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 2a48103147..90bc64bd2b 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -224,7 +224,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
}
ProFile *QMakeParser::parsedProBlock(
- const QString &contents, const QString &name, int line, SubGrammar grammar)
+ const QStringRef &contents, const QString &name, int line, SubGrammar grammar)
{
ProFile *pro = new ProFile(name);
read(pro, contents, line, grammar);
@@ -247,7 +247,7 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags)
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
return false;
}
- read(pro, content, 1, FullGrammar);
+ read(pro, QStringRef(&content), 1, FullGrammar);
return true;
}
@@ -289,7 +289,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len)
buf[-2] = (ushort)(hash >> 16);
}
-void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
+void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar grammar)
{
m_proFile = pro;
m_lineNo = line;
@@ -334,8 +334,8 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
QStack<ParseCtx> xprStack;
xprStack.reserve(10);
- // We rely on QStrings being null-terminated, so don't maintain a global end pointer.
const ushort *cur = (const ushort *)in.unicode();
+ const ushort *inend = cur + in.length();
m_canElse = false;
freshLine:
m_state = StNew;
@@ -418,7 +418,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
int indent;
if (context == CtxPureValue) {
- end = (const ushort *)in.unicode() + in.length();
+ end = inend;
cptr = 0;
lineCont = false;
indent = 0; // just gcc being stupid
@@ -430,24 +430,30 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
// First, skip leading whitespace
for (indent = 0; ; ++cur, ++indent) {
+ if (cur == inend) {
+ cur = 0;
+ goto flushLine;
+ }
c = *cur;
if (c == '\n') {
++cur;
goto flushLine;
- } else if (!c) {
- cur = 0;
- goto flushLine;
- } else if (c != ' ' && c != '\t' && c != '\r') {
- break;
}
+ if (c != ' ' && c != '\t' && c != '\r')
+ break;
}
// Then strip comments. Yep - no escaping is possible.
for (cptr = cur;; ++cptr) {
+ if (cptr == inend) {
+ end = cptr;
+ break;
+ }
c = *cptr;
if (c == '#') {
- for (end = cptr; (c = *++cptr);) {
- if (c == '\n') {
+ end = cptr;
+ while (++cptr < inend) {
+ if (*cptr == '\n') {
++cptr;
break;
}
@@ -460,10 +466,6 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
}
break;
}
- if (!c) {
- end = cptr;
- break;
- }
if (c == '\n') {
end = cptr++;
break;
@@ -1215,7 +1217,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
ushort **buf, QString *xprBuff,
ushort **tokPtr, QString *tokBuff,
- const ushort *cur, const QString &in)
+ const ushort *cur, const QStringRef &in)
{
QString out;
m_tmp.setRawData((const QChar *)xprPtr, tlen);
diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h
index f78b3215bb..f8ff2fc3cc 100644
--- a/qmake/library/qmakeparser.h
+++ b/qmake/library/qmakeparser.h
@@ -87,7 +87,7 @@ public:
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
// fileName is expected to be absolute and cleanPath()ed.
ProFile *parsedProFile(const QString &fileName, ParseFlags flags = ParseDefault);
- ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
+ ProFile *parsedProBlock(const QStringRef &contents, const QString &name, int line = 0,
SubGrammar grammar = FullGrammar);
void discardFileFromCache(const QString &fileName);
@@ -130,7 +130,7 @@ private:
};
bool read(ProFile *pro, ParseFlags flags);
- void read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
+ void read(ProFile *pro, const QStringRef &content, int line, SubGrammar grammar);
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
@@ -141,7 +141,7 @@ private:
ALWAYS_INLINE bool resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
ushort **buf, QString *xprBuff,
ushort **tokPtr, QString *tokBuff,
- const ushort *cur, const QString &in);
+ const ushort *cur, const QStringRef &in);
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
void warnOperator(const char *msg);
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 01adb7422c..28a6c72a46 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -120,7 +120,8 @@ QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList>
ProString QMakeProject::expand(const QString &expr, const QString &where, int line)
{
ProString ret;
- ProFile *pro = m_parser->parsedProBlock(expr, where, line, QMakeParser::ValueGrammar);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&expr), where, line,
+ QMakeParser::ValueGrammar);
if (pro->isOk()) {
m_current.pro = pro;
m_current.line = 0;
diff --git a/qmake/project.h b/qmake/project.h
index aa9f7dfb3b..4986c7c82d 100644
--- a/qmake/project.h
+++ b/qmake/project.h
@@ -55,7 +55,7 @@ public:
ProString expand(const QString &v, const QString &file, int line);
QStringList expand(const ProKey &func, const QList<ProStringList> &args);
bool test(const QString &v, const QString &file, int line)
- { m_current.clear(); return evaluateConditional(v, file, line); }
+ { m_current.clear(); return evaluateConditional(QStringRef(&v), file, line); }
bool test(const ProKey &func, const QList<ProStringList> &args);
bool isSet(const ProKey &v) const { return m_valuemapStack.first().contains(v); }
@@ -64,6 +64,8 @@ public:
int intValue(const ProKey &v, int defaultValue = 0) const;
const ProValueMap &variables() const { return m_valuemapStack.first(); }
ProValueMap &variables() { return m_valuemapStack.first(); }
+ bool isActiveConfig(const QString &config, bool regex = false)
+ { return QMakeEvaluator::isActiveConfig(QStringRef(&config), regex); }
void dump() const;
@@ -78,7 +80,6 @@ public:
using QMakeEvaluator::propertyValue;
using QMakeEvaluator::values;
using QMakeEvaluator::first;
- using QMakeEvaluator::isActiveConfig;
using QMakeEvaluator::isHostBuild;
using QMakeEvaluator::dirSep;
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 782151d763..7f49bb9adb 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -11,8 +11,7 @@ SOURCES += project.cpp property.cpp main.cpp \
generators/win32/msvc_nmake.cpp generators/projectgenerator.cpp \
generators/win32/msvc_vcproj.cpp \
generators/win32/msvc_vcxproj.cpp \
- generators/win32/msvc_objectmodel.cpp generators/win32/msbuild_objectmodel.cpp \
- generators/win32/cesdkhandler.cpp
+ generators/win32/msvc_objectmodel.cpp generators/win32/msbuild_objectmodel.cpp
HEADERS += project.h property.h \
library/qmake_global.h library/ioutils.h library/proitems.h library/qmakevfs.h library/qmakeglobals.h \
@@ -24,8 +23,7 @@ HEADERS += project.h property.h \
generators/xmloutput.h generators/win32/msvc_nmake.h \
generators/win32/msvc_vcproj.h \
generators/win32/msvc_vcxproj.h \
- generators/win32/msvc_objectmodel.h generators/win32/msbuild_objectmodel.h \
- generators/win32/cesdkhandler.h
+ generators/win32/msvc_objectmodel.h generators/win32/msbuild_objectmodel.h
bootstrap { #Qt code
SOURCES+= \