Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Ie56539b2e0be611a363b5f15ae5412a78d6945a2bb10
commit
840f6a40e6
|
|
@ -1,3 +0,0 @@
|
|||
OBJECTIVE_SOURCES = coreservices.mm
|
||||
LIBS += -framework CoreServices
|
||||
CONFIG -= qt
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
SOURCES = ptrsizetest.cpp
|
||||
CONFIG -= qt dylib
|
||||
CONFIG += debug console
|
||||
|
|
|
|||
|
|
@ -1609,8 +1609,8 @@ while [ "$#" -gt 0 ]; do
|
|||
[ "$XPLATFORM" = "undefined" ] && exit 101
|
||||
;;
|
||||
device-option)
|
||||
DEV_VAR=`echo $VAL | sed "s,^\(.*\)=.*,\1,"`
|
||||
DEV_VAL=`echo $VAL | sed "s,^.*=\(.*\),\1,"`
|
||||
DEV_VAR=`echo $VAL | cut -d '=' -f 1`
|
||||
DEV_VAL=`echo $VAL | cut -d '=' -f 2-`
|
||||
DeviceVar set $DEV_VAR "$DEV_VAL"
|
||||
;;
|
||||
qpa)
|
||||
|
|
@ -2882,7 +2882,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
|
|||
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests"
|
||||
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
|
||||
CFG_CXX11="no" # C++11 support disabled for now
|
||||
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples"
|
||||
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmacextras qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples"
|
||||
fi
|
||||
|
||||
# disable GTK style support auto-detection on Mac
|
||||
|
|
@ -3032,6 +3032,21 @@ unset tty
|
|||
|
||||
eval `LC_ALL=C $TEST_COMPILER $SYSROOT_FLAG $TEST_COMPILER_CXXFLAGS -xc++ -E -v - < /dev/null 2>&1 > /dev/null | $AWK '
|
||||
BEGIN { ORS = ""; FS = "="; incs = 0; libs = 0; }
|
||||
|
||||
function normalize(dir)
|
||||
{
|
||||
do {
|
||||
odir = dir
|
||||
gsub(/\\/[^\\/]+\\/\\.\\./, "", dir)
|
||||
} while (dir != odir);
|
||||
do {
|
||||
odir = dir
|
||||
gsub(/\\/\\./, "", dir)
|
||||
} while (dir != odir);
|
||||
sub("/$", "", dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
function quote(s)
|
||||
{
|
||||
# We only handle spaces
|
||||
|
|
@ -3047,14 +3062,19 @@ function quote(s)
|
|||
/^\#include </ { yup=1; print "DEFAULT_INCDIRS=\""; next }
|
||||
/^End of search/ { yup=0; print "\"\n" }
|
||||
/ \(framework directory\)$/ { next }
|
||||
yup { print quote(substr($0, 2)) " "; ++incs }
|
||||
yup { print quote(normalize(substr($0, 2))) " "; ++incs }
|
||||
|
||||
# extract from one line like LIBRARY_PATH=/one/path:/another/path:...
|
||||
$1 == "LIBRARY_PATH" {
|
||||
libs = split($2, library_paths, ":");
|
||||
print "DEFAULT_LIBDIRS=\"";
|
||||
for (lib in library_paths)
|
||||
print quote(library_paths[lib]) " ";
|
||||
for (lib in library_paths) {
|
||||
dir = normalize(library_paths[lib]);
|
||||
if (!(dir in dirs)) {
|
||||
print quote(dir) " ";
|
||||
dirs[dir] = 1;
|
||||
}
|
||||
}
|
||||
print "\"\n"
|
||||
}
|
||||
|
||||
|
|
@ -4230,7 +4250,7 @@ fi
|
|||
#-------------------------------------------------------------------------------
|
||||
# Verify makespec
|
||||
#-------------------------------------------------------------------------------
|
||||
QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1 >/dev/null`
|
||||
QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1`
|
||||
if [ $? != "0" ]; then
|
||||
echo "Failed to process makespec for platform '$XPLATFORM'"
|
||||
if [ "$OPT_VERBOSE" = "yes" ]; then
|
||||
|
|
@ -5501,6 +5521,7 @@ elif [ "$CFG_EGL" != "no" ]; then
|
|||
QMAKE_CFLAGS_EGL=`$PKG_CONFIG --cflags egl 2>/dev/null`
|
||||
QMakeVar set QMAKE_INCDIR_EGL "$QMAKE_INCDIR_EGL"
|
||||
QMakeVar set QMAKE_LIBS_EGL "$QMAKE_LIBS_EGL"
|
||||
QMakeVar set QMAKE_CFLAGS_EGL "`echo " $QMAKE_CFLAGS_EGL " | sed -e 's, -I[^ ]* , ,g;s,^ ,,;s, $,,'`"
|
||||
fi # detect EGL support
|
||||
if compileTest qpa/egl "EGL" $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then
|
||||
CFG_EGL=yes
|
||||
|
|
@ -5582,14 +5603,6 @@ if [ "$CFG_KMS" = "yes" ]; then
|
|||
QT_CONFIG="$QT_CONFIG kms"
|
||||
fi
|
||||
|
||||
if [ "$BUILD_ON_MAC" = "yes" ]; then
|
||||
if compileTest mac/coreservices "CoreServices"; then
|
||||
QT_CONFIG="$QT_CONFIG coreservices"
|
||||
else
|
||||
QMakeVar add DEFINES QT_NO_CORESERVICES
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$BUILD_ON_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ] && [ "$XPLATFORM_QNX" = "no" ] && [ "$XPLATFORM_ANDROID" = "no" ]; then
|
||||
if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ] && [ "$CFG_DIRECTFB" = "no" ] && [ "$CFG_LINUXFB" = "no" ] && [ "$CFG_KMS" = "no" ]; then
|
||||
if [ "$QPA_PLATFORM_GUARD" = "yes" ] &&
|
||||
|
|
@ -6898,7 +6911,7 @@ report_support " FreeType ..............." "$CFG_FREETYPE"
|
|||
report_support " Iconv .................." "$CFG_ICONV"
|
||||
report_support " ICU ...................." "$CFG_ICU"
|
||||
report_support " Image formats:"
|
||||
report_support_plugin " GIF .................." "$CFG_GIF" system QtGui
|
||||
report_support_plugin " GIF .................." "$CFG_GIF" qt QtGui
|
||||
report_support_plugin " JPEG ................." "$CFG_JPEG" "$CFG_LIBJPEG" QtGui
|
||||
report_support_plugin " PNG .................." "$CFG_PNG" "$CFG_LIBPNG" QtGui
|
||||
report_support " Glib ..................." "$CFG_GLIB"
|
||||
|
|
|
|||
|
|
@ -84,3 +84,22 @@ QtGui
|
|||
related to session management. For platform that don't support this
|
||||
feature the default behavior has not changed.
|
||||
Both X11 and Windows session management are supported.
|
||||
|
||||
QtNetwork
|
||||
---------
|
||||
|
||||
- API was added to store and resume TLS session tickets.
|
||||
|
||||
- The minimum support openssl version has been increased to openssl 1.0. The
|
||||
code to support older versions has not been removed, but is no longer
|
||||
supported.
|
||||
|
||||
- An off-by-one error in NTLM proxy authentication has been fixed.
|
||||
|
||||
- Various improvements to reduce the memory used by qtnetwork have been made.
|
||||
|
||||
- Improved support for HTTP proxy authentication.
|
||||
|
||||
- Support for preconnecting to servers before making HTTP and HTTPS
|
||||
connections. This allows for much reduced latency when the hosts to be
|
||||
connected to are known.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
requires(qtHaveModule(gui))
|
||||
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += no_docs_target
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
requires(qtHaveModule(gui))
|
||||
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = windows
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@
|
|||
#include <QGuiApplication>
|
||||
#include <qtconcurrentmap.h>
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
|
||||
QImage scale(const QImage &image)
|
||||
{
|
||||
qDebug() << "Scaling image in thread" << QThread::currentThread();
|
||||
|
|
@ -70,23 +68,3 @@ int main(int argc, char *argv[])
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QString text("Qt Concurrent is not yet supported on this platform");
|
||||
|
||||
QLabel *label = new QLabel(text);
|
||||
label->setWordWrap(true);
|
||||
|
||||
label->show();
|
||||
qDebug() << text;
|
||||
|
||||
app.exec();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ SUBDIRS = imagescaling \
|
|||
SUBDIRS += progressdialog
|
||||
}
|
||||
|
||||
!qtHaveModule(gui) {
|
||||
SUBDIRS -= \
|
||||
map
|
||||
}
|
||||
|
||||
!qtHaveModule(widgets) {
|
||||
SUBDIRS -= \
|
||||
imagescaling \
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtCore>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
SOURCES += semaphores.cpp
|
||||
QT = core gui
|
||||
QT = core
|
||||
|
||||
CONFIG -= app_bundle
|
||||
CONFIG += console
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtCore>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
QT = core gui
|
||||
QT = core
|
||||
CONFIG -= moc app_bundle
|
||||
CONFIG += console
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
|
|||
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
|
||||
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
|
||||
|
||||
QMAKE_LIBS = -lgnustl_shared -lsupc++ -llog -lz -lm -ldl -lc -lgcc
|
||||
QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc
|
||||
QMAKE_LIBS_X11 =
|
||||
QMAKE_LIBS_THREAD =
|
||||
QMAKE_LIBS_EGL = -lEGL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# qmake configuration for blackberry armv7le systems
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
DEFINES += Q_OS_BLACKBERRY
|
||||
CONFIG += blackberry
|
||||
LIBS += -lbps
|
||||
|
||||
# Blackberry also has support for stack smashing protection in its libc
|
||||
contains(QT_CONFIG, stack-protector-strong) {
|
||||
QMAKE_CFLAGS += -fstack-protector-strong
|
||||
} else {
|
||||
QMAKE_CFLAGS += -fstack-protector -fstack-protector-all
|
||||
}
|
||||
|
||||
QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
|
||||
|
||||
QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now
|
||||
|
||||
include(../common/qcc-base-qnx-armv7le.conf)
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the config.tests of the Qt Toolkit.
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
|
|
@ -39,10 +39,4 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
FSRef ref;
|
||||
return 0;
|
||||
}
|
||||
#include "../qnx-armv7le-qcc/qplatformdefs.h"
|
||||
|
|
@ -1,22 +1,5 @@
|
|||
#
|
||||
# qmake configuration for blackberry armv7le systems
|
||||
# deprecated, please use blackberry-armle-v7-qcc instead
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
DEFINES += Q_OS_BLACKBERRY
|
||||
CONFIG += blackberry
|
||||
LIBS += -lbps
|
||||
|
||||
# Blackberry also has support for stack smashing protection in its libc
|
||||
contains(QT_CONFIG, stack-protector-strong) {
|
||||
QMAKE_CFLAGS += -fstack-protector-strong
|
||||
} else {
|
||||
QMAKE_CFLAGS += -fstack-protector -fstack-protector-all
|
||||
}
|
||||
|
||||
QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
|
||||
|
||||
QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now
|
||||
|
||||
include(../common/qcc-base-qnx-armv7le.conf)
|
||||
warning("You are using deprecated mkspecs. Please use blackberry-armle-v7-qcc instead.")
|
||||
include(../blackberry-armle-v7-qcc/qmake.conf)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Research In Motion Limited. <blackberry-qt@qnx.com>
|
||||
** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
|
|
@ -39,4 +39,4 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../qnx-armv7le-qcc/qplatformdefs.h"
|
||||
#include "../blackberry-armle-v7-qcc/qplatformdefs.h"
|
||||
|
|
|
|||
|
|
@ -14,3 +14,4 @@ QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY
|
|||
QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK
|
||||
# xcopy copies the contained files if source is a directory. Deal with it.
|
||||
CONFIG += copy_dir_files
|
||||
QMAKE_STREAM_EDITOR = $(QMAKE) -install sed
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# qmake configuration for the Blackberry Playbook armv7le
|
||||
#
|
||||
|
||||
include(../../blackberry-armle-v7-qcc/qmake.conf)
|
||||
|
||||
DEFINES += Q_OS_BLACKBERRY_TABLET
|
||||
CONFIG += blackberry-playbook
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Klarälvdalens Datakonsult AB <info@kdab.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../blackberry-armle-v7-qcc/qplatformdefs.h"
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
#
|
||||
# qmake configuration for the Blackberry Playbook armv7le
|
||||
# deprecated, please use blackberry-playbook-armle-v7-qcc instead
|
||||
#
|
||||
|
||||
include(../../blackberry-armv7le-qcc/qmake.conf)
|
||||
|
||||
DEFINES += Q_OS_BLACKBERRY_TABLET
|
||||
CONFIG += blackberry-playbook
|
||||
warning("You are using deprecated mkspecs. Please use blackberry-playbook-armle-v7-qcc instead.")
|
||||
include(../blackberry-playbook-armle-v7-qcc/qmake.conf)
|
||||
|
|
|
|||
|
|
@ -39,4 +39,4 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../blackberry-armv7le-qcc/qplatformdefs.h"
|
||||
#include "../blackberry-playbook-armle-v7-qcc/qplatformdefs.h"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "qeglfshooks.h"
|
||||
#include <EGL/eglvivante.h>
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -62,6 +63,15 @@ private:
|
|||
QEglFSImx6Hooks::QEglFSImx6Hooks()
|
||||
{
|
||||
int width, height;
|
||||
|
||||
bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER");
|
||||
bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER");
|
||||
if (multiBufferNotEnabledYet && multiBuffer) {
|
||||
qWarning() << "QEglFSImx6Hooks will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n"
|
||||
<< "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1";
|
||||
qputenv("FB_MULTI_BUFFER", "2");
|
||||
}
|
||||
|
||||
mNativeDisplay = fbGetDisplayByIndex(0);
|
||||
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
|
||||
mScreenSize.setHeight(height);
|
||||
|
|
|
|||
|
|
@ -136,89 +136,6 @@ static void destroyDispmanxLayer(EGLNativeWindowType window)
|
|||
delete eglWindow;
|
||||
}
|
||||
|
||||
class QEglFSPiCursor : public QEglFSCursor
|
||||
{
|
||||
public:
|
||||
QEglFSPiCursor(QEglFSScreen *screen) : QEglFSCursor(screen) {
|
||||
QSurfaceFormat platformFormat;
|
||||
platformFormat.setDepthBufferSize(24);
|
||||
platformFormat.setStencilBufferSize(8);
|
||||
platformFormat.setRedBufferSize(8);
|
||||
platformFormat.setGreenBufferSize(8);
|
||||
platformFormat.setBlueBufferSize(8);
|
||||
platformFormat.setAlphaBufferSize(8);
|
||||
m_config = q_configFromGLFormat(m_screen->display(), platformFormat);
|
||||
|
||||
createSurface();
|
||||
createContext();
|
||||
drawInLayer();
|
||||
}
|
||||
|
||||
~QEglFSPiCursor() {
|
||||
eglDestroySurface(m_screen->display(), m_surface);
|
||||
destroyDispmanxLayer(m_window);
|
||||
eglDestroyContext(m_screen->display(), m_context);
|
||||
}
|
||||
|
||||
void createSurface() {
|
||||
const QRect cr = cursorRect();
|
||||
m_window = createDispmanxLayer(cr.topLeft(), cr.size(), 50, DISPMANX_FLAGS_ALPHA_FROM_SOURCE);
|
||||
m_surface = eglCreateWindowSurface(m_screen->display(), m_config, m_window, NULL);
|
||||
}
|
||||
|
||||
void createContext() {
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
QVector<EGLint> attrs;
|
||||
attrs.append(EGL_CONTEXT_CLIENT_VERSION);
|
||||
attrs.append(2);
|
||||
attrs.append(EGL_NONE);
|
||||
m_context = eglCreateContext(m_screen->display(), m_config, EGL_NO_CONTEXT, attrs.constData());
|
||||
}
|
||||
|
||||
void drawInLayer() {
|
||||
eglMakeCurrent(m_screen->display(), m_surface, m_surface, m_context);
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
draw(QRectF(QPointF(-1, 1), QPointF(1, -1)));
|
||||
|
||||
eglSwapBuffers(m_screen->display(), m_surface);
|
||||
eglMakeCurrent(m_screen->display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE {
|
||||
if (!setCurrentCursor(cursor))
|
||||
return;
|
||||
|
||||
EGL_DISPMANX_WINDOW_T *eglWindow = static_cast<EGL_DISPMANX_WINDOW_T *>(m_window);
|
||||
if (QSize(eglWindow->width, eglWindow->height) != m_cursor.size) {
|
||||
eglDestroySurface(m_screen->display(), m_surface);
|
||||
destroyDispmanxLayer(m_window);
|
||||
createSurface();
|
||||
}
|
||||
drawInLayer();
|
||||
}
|
||||
|
||||
void setPos(const QPoint &pos) Q_DECL_OVERRIDE {
|
||||
m_cursor.pos = pos;
|
||||
moveDispmanxLayer(m_window, cursorRect().topLeft());
|
||||
}
|
||||
|
||||
void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE {
|
||||
if (event.type() != QEvent::MouseMove)
|
||||
return;
|
||||
m_cursor.pos = event.pos();
|
||||
moveDispmanxLayer(m_window, cursorRect().topLeft());
|
||||
}
|
||||
|
||||
void paintOnScreen() Q_DECL_OVERRIDE { }
|
||||
private:
|
||||
EGLConfig m_config;
|
||||
EGLContext m_context;
|
||||
EGLNativeWindowType m_window;
|
||||
EGLSurface m_surface;
|
||||
};
|
||||
|
||||
class QEglFSPiHooks : public QEglFSHooks
|
||||
{
|
||||
public:
|
||||
|
|
@ -230,9 +147,6 @@ public:
|
|||
virtual void destroyNativeWindow(EGLNativeWindowType window);
|
||||
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
|
||||
|
||||
QEglFSCursor *createCursor(QEglFSScreen *screen) const {
|
||||
return new QEglFSPiCursor(screen);
|
||||
}
|
||||
};
|
||||
|
||||
void QEglFSPiHooks::platformInit()
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk {
|
|||
else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
|
||||
}
|
||||
FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX),"
|
||||
FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX),"
|
||||
|
||||
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
|
||||
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
|
||||
|
|
@ -61,9 +62,6 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk {
|
|||
!isEmpty(ANDROID_EXTRA_LIBS): \
|
||||
FILE_CONTENT += " \"android-extra-libs\": $$emitString($$join(ANDROID_EXTRA_LIBS, ",")),"
|
||||
|
||||
!isEmpty(QMAKE_SUPPORTED_ORIENTATIONS): \
|
||||
FILE_CONTENT += " \"supported-orientations\": $$emitString($$join(QMAKE_SUPPORTED_ORIENTATIONS, ",")),"
|
||||
|
||||
FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)"
|
||||
FILE_CONTENT += "}"
|
||||
|
||||
|
|
|
|||
|
|
@ -30,11 +30,19 @@ split_incpath {
|
|||
CMAKE_ADD_SOURCE_INCLUDE_DIRS = true
|
||||
CMAKE_NO_PRIVATE_INCLUDES = true # Don't add private includes in the build dir which don't exist
|
||||
CMAKE_SOURCE_INCLUDES = \
|
||||
$$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE) \
|
||||
$$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME})
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME})
|
||||
CMAKE_SOURCE_PRIVATE_INCLUDES = \
|
||||
$$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)) \
|
||||
$$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME})
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION) \
|
||||
$$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME})
|
||||
|
||||
cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in
|
||||
cmake_extra_source_includes.output = $$DESTDIR/cmake/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake
|
||||
|
||||
!build_pass:QMAKE_SUBSTITUTES += \
|
||||
cmake_extra_source_includes
|
||||
|
||||
cmake_qt5_module_files.files = \
|
||||
$$cmake_extra_source_includes.output
|
||||
}
|
||||
|
||||
CMAKE_INCLUDE_DIR = $$cmakeRelativePath($$[QT_INSTALL_HEADERS], $$[QT_INSTALL_PREFIX])
|
||||
|
|
@ -68,7 +76,7 @@ contains(CMAKE_PLUGIN_DIR, "^\\.\\./.*") {
|
|||
CMAKE_PLUGIN_DIR_IS_ABSOLUTE = True
|
||||
}
|
||||
|
||||
!isEmpty(DLLDESTDIR):!static:!staticlib {
|
||||
win32:!wince:!static:!staticlib {
|
||||
CMAKE_DLL_DIR = $$cmakeRelativePath($$[QT_INSTALL_BINS], $$[QT_INSTALL_PREFIX])
|
||||
contains(CMAKE_DLL_DIR, "^\\.\\./.*") {
|
||||
CMAKE_DLL_DIR = $$[QT_INSTALL_BINS]/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS
|
||||
$$CMAKE_SOURCE_INCLUDES
|
||||
)
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
|
||||
$$CMAKE_SOURCE_PRIVATE_INCLUDES
|
||||
)
|
||||
|
|
@ -121,12 +121,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
|
|||
!!ENDIF
|
||||
!!ENDIF
|
||||
!!IF !isEmpty(CMAKE_ADD_SOURCE_INCLUDE_DIRS)
|
||||
list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS
|
||||
$$CMAKE_SOURCE_INCLUDES
|
||||
)
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
|
||||
$$CMAKE_SOURCE_PRIVATE_INCLUDES
|
||||
)
|
||||
include(\"${CMAKE_CURRENT_LIST_DIR}/ExtraSourceIncludes.cmake\" OPTIONAL)
|
||||
!!ENDIF
|
||||
!!ELSE
|
||||
set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,18 @@ contains(TEMPLATE, ".*(lib|app)"):CONFIG += have_target
|
|||
|
||||
load(resolve_config)
|
||||
|
||||
# If the TARGET looks like a path, split it into DESTDIR and the resulting TARGET
|
||||
target_dir_part = $$dirname(TARGET)
|
||||
!isEmpty(target_dir_part) {
|
||||
isEmpty(DESTDIR): \
|
||||
DESTDIR = $$target_dir_part
|
||||
else: \
|
||||
DESTDIR = $$DESTDIR/$$target_dir_part
|
||||
|
||||
TARGET = $$basename(TARGET)
|
||||
DESTDIR = $$clean_path($$DESTDIR)
|
||||
}
|
||||
|
||||
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
||||
!isEmpty(QT_BREAKPAD_ROOT_PATH): \ # quick test first whether requested ...
|
||||
!static:release:have_target: \ # is it applicable?
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ wince*:contains(QT_CONFIG, opengles1) {
|
|||
} else {
|
||||
INCLUDEPATH += $$QMAKE_INCDIR_EGL
|
||||
LIBS_PRIVATE += $$QMAKE_LIBS_EGL
|
||||
QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
|
||||
LIBS += $$QMAKE_LFLAGS_EGL
|
||||
for(p, QMAKE_LIBDIR_EGL) {
|
||||
exists($$p):LIBS_PRIVATE += -L$$p
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
load(default_pre)
|
||||
|
||||
# Check for supported Xcode versions
|
||||
lessThan(QMAKE_XCODE_VERSION, "4.3"): \
|
||||
error("This mkspec requires Xcode 4.3 or later")
|
||||
!contains(QMAKE_XCODE_VERSION, ^(4\\.[3456]|5\\.[0])$): \
|
||||
warning("The version of Xcode installed on this system ($$QMAKE_XCODE_VERSION)" \
|
||||
"has not been tested fully - custom compiler settings may be necessary")
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
|
||||
equals(TEMPLATE, app):contains(QT, gui(-private)?) {
|
||||
!macx-xcode: \
|
||||
error("Linking the iOS platform plugin requires bulding through Xcode")
|
||||
|
||||
LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
|
||||
|
||||
lib_name = qios
|
||||
lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
|
||||
LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
|
||||
|
||||
# By marking qt_registerPlatformPlugin as undefined, we ensure that
|
||||
# the plugin.o translation unit is considered for inclusion in
|
||||
# the final binary, which in turn ensures that the plugin's
|
||||
# static initializer is included and run.
|
||||
QMAKE_LFLAGS += -u _qt_registerPlatformPlugin
|
||||
|
||||
# We do link and dependency resolution for the platform plugin
|
||||
# manually, since we know we always need the plugin, so we don't
|
||||
# need to generate an import for it.
|
||||
CONFIG -= import_qpa_plugin
|
||||
|
||||
!no_main_wrapper {
|
||||
# Instead of messing with the user's main function we go the other
|
||||
# way and change the application entry point to call our main wrapper.
|
||||
# This entry point is the 'start' symbol, provided by crt1.o, so we
|
||||
# make a copy of the file and rename the '_main' unresolved symbol
|
||||
# to our wrapper function, '_qtmn', injecting ourselves into the app
|
||||
# startup. Once Apple starts shipping the LLVM linker (lld) we may
|
||||
# get rid of this step completely and just pass -e _qtmn to the
|
||||
# linker, taking advantage of the new LC_MAIN load command.
|
||||
|
||||
# We know that iOS 3.1 and up uses crt1.3.1.o (technically not
|
||||
# true for simulator, but the SDK has a symlink to the correct file).
|
||||
original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o"
|
||||
|
||||
xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)"
|
||||
custom_crt_filename = "crt1_qt.o"
|
||||
custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename"
|
||||
|
||||
EOC = $$escape_expand(\\n\\t)
|
||||
create_custom_crt.commands = \
|
||||
# Copy original crt1 to build directory
|
||||
"$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \
|
||||
# And rename all occurrences of _main to _qtmn
|
||||
"strings -t d - $${custom_crt_path}" \
|
||||
"| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \
|
||||
"| while read offset; do" \
|
||||
"printf '_qtmn'" \
|
||||
"| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \
|
||||
"; done"
|
||||
create_custom_crt.depends = $$original_crt_path
|
||||
create_custom_crt.target = $$custom_crt_path
|
||||
preprocess.depends = create_custom_crt
|
||||
QMAKE_EXTRA_TARGETS += create_custom_crt preprocess
|
||||
|
||||
clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path"
|
||||
preprocess_clean.depends += clean_custom_crt
|
||||
QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean
|
||||
|
||||
# Prevent usage of new LC_MAIN load command, which skips start/crt1
|
||||
# and calls main from the loader. We rely on injecting into start.
|
||||
QMAKE_LFLAGS += -Wl,-no_new_main
|
||||
|
||||
# Explicitly link against our modified crt1 object
|
||||
QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename}
|
||||
|
||||
# Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables
|
||||
lib_search_path.name = LIBRARY_SEARCH_PATHS
|
||||
lib_search_path.value = $$xcode_objects_path
|
||||
QMAKE_MAC_XCODE_SETTINGS += lib_search_path
|
||||
}
|
||||
}
|
||||
|
||||
load(qt)
|
||||
|
|
@ -23,3 +23,9 @@ isEmpty(QMAKE_XCODE_VERSION) {
|
|||
isEmpty(QMAKE_XCODE_VERSION): error("Could not resolve Xcode version.")
|
||||
unset(xcode_version)
|
||||
}
|
||||
|
||||
# These two variables are used by the xcode_dynamic_library_suffix
|
||||
# feature, which allows Xcode to choose the Qt libraries to link to
|
||||
# at build time, depending on the current Xcode SDK and configuration.
|
||||
QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix()
|
||||
QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ if(win32|mac):!macx-xcode {
|
|||
}
|
||||
isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name)
|
||||
|
||||
# Insert the plugins URI into its meta data to enable usage
|
||||
# of static plugins in QtDeclarative:
|
||||
URI = $$replace(TARGETPATH, "/", ".")
|
||||
QMAKE_MOC_OPTIONS += -Muri=$$URI
|
||||
|
||||
QMLTYPEFILE = $$_PRO_FILE_PWD_/plugins.qmltypes
|
||||
exists($$QMLTYPEFILE): QML_FILES += $$QMLTYPEFILE
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,88 @@ wince*:static:gui {
|
|||
QTLIB += qmenu_wce.res
|
||||
}
|
||||
|
||||
# static builds: link qml import plugins into the app.
|
||||
if(contains(QT, qml)|contains(QT_PRIVATE, qml)): \
|
||||
contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan {
|
||||
# run qmlimportscanner
|
||||
qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner)
|
||||
for (MODULE, QT_MODULES) {
|
||||
PATH = $$eval(QT.$${MODULE}.qml)
|
||||
!isEmpty(PATH): QMLPATHS += $$PATH
|
||||
}
|
||||
QMLPATHS = $$unique(QMLPATHS)
|
||||
for (QMLPATH, QMLPATHS): \
|
||||
IMPORTPATHS += -importPath $$QMLPATH
|
||||
|
||||
#message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS)
|
||||
JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS)
|
||||
|
||||
parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.")
|
||||
|
||||
!isEmpty(IMPORTS._KEYS_) {
|
||||
# add import plugins to LIBS line
|
||||
for (key, IMPORTS._KEYS_): {
|
||||
PATH = $$eval(IMPORTS.$${key}.path)
|
||||
PLUGIN = $$eval(IMPORTS.$${key}.plugin)
|
||||
!isEmpty(PATH):!isEmpty(PLUGIN): LIBS *= -L$$PATH -l$$PLUGIN
|
||||
}
|
||||
|
||||
# create qml_plugin_import.cpp
|
||||
IMPORT_FILE_CONT = \
|
||||
"// This file is autogenerated by qmake. It imports static plugin classes for" \
|
||||
"// static plugins used by QML imports." \
|
||||
"$${LITERAL_HASH}include <QtPlugin>"
|
||||
for (key, IMPORTS._KEYS_) {
|
||||
PLUGIN = $$eval(IMPORTS.$${key}.plugin)
|
||||
CLASSNAME = $$eval(IMPORTS.$${key}.classname)
|
||||
!isEmpty(PLUGIN) {
|
||||
!isEmpty(CLASSNAME) {
|
||||
!contains(ADDED_IMPORTS, $$PLUGIN) {
|
||||
ADDED_IMPORTS += $$PLUGIN
|
||||
IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$CLASSNAME)"
|
||||
}
|
||||
} else {
|
||||
error("Plugin $$PLUGIN is missing a classname entry, please add one to the qmldir file.")
|
||||
}
|
||||
}
|
||||
}
|
||||
QML_IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_qml_plugin_import.cpp
|
||||
write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error("Aborting.")
|
||||
SOURCES += $$QML_IMPORT_CPP
|
||||
QMAKE_CLEAN += $$QML_IMPORT_CPP
|
||||
|
||||
# copy qml files. this part is platform spesific.
|
||||
macx {
|
||||
# copy to Contents/Resources in the bundle.
|
||||
QmlImports.path = Contents/Resources/
|
||||
QmlImports.files *= $$QMLPATHS
|
||||
QMAKE_BUNDLE_DATA += QmlImports
|
||||
|
||||
# place qt.conf in Contents/Resources in the app bundle
|
||||
QT_CONF_CONTENTS = \
|
||||
"[Paths]" \
|
||||
"Imports = Resources/qml" \
|
||||
"Qml2Imports = Resources/qml"
|
||||
QT_CONF = "$$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf"
|
||||
write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.")
|
||||
} else: ios {
|
||||
# flat bundle layout (no Contents/Resources)
|
||||
QmlImports.files *= $$QMLPATHS
|
||||
QMAKE_BUNDLE_DATA += QmlImports
|
||||
|
||||
# write qt.conf to OUT_PWD and make xcode copy it via QMAKE_BUNDLE_DATA
|
||||
QT_CONF_CONTENTS = \
|
||||
"[Paths]" \
|
||||
"Imports = qml" \
|
||||
"Qml2Imports = qml"
|
||||
QT_CONF = "$$OUT_PWD/qt.conf"
|
||||
write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.")
|
||||
QtConf.files = $$QT_CONF
|
||||
QMAKE_BUNDLE_DATA += QtConf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN
|
||||
contains(QT_CONFIG, static) {
|
||||
QT_PLUGIN_VERIFY += QTPLUGIN
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ QMAKE_QT_CONFIG = $$[QT_HOST_DATA/get]/mkspecs/qconfig.pri
|
|||
include($$mod)
|
||||
}
|
||||
}
|
||||
QT_MODULES = $$unique(QT_MODULES) # In case modules appear in multiple places
|
||||
unset(QT_MODULE_INCLUDE_BASE)
|
||||
unset(QT_MODULE_LIB_BASE)
|
||||
unset(QT_MODULE_HOST_LIB_BASE)
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ defineReplace(qtLibraryTarget) {
|
|||
}
|
||||
|
||||
defineTest(qtAddLibrary) {
|
||||
warning("qtAddLibrary() is deprecated. Use qtAddModule() or QT+= instead.")
|
||||
warning("qtAddLibrary() is deprecated. Use QT+= instead.")
|
||||
|
||||
# Reverse-engineer the module name from the library name.
|
||||
for(var, QT_MODULES) {
|
||||
isEqual(QT.$${var}.name, $$1) {
|
||||
qtAddModule($$var, , LIBS)
|
||||
return(true):break() # Yes, the break is insanity. But necessary.
|
||||
return(true)
|
||||
}
|
||||
}
|
||||
error("No module matching library '$$1' found.")
|
||||
|
|
|
|||
|
|
@ -36,11 +36,34 @@ CONFIG(debug, debug|release): \
|
|||
else: \
|
||||
CONFIG -= debug
|
||||
|
||||
debug_and_release {
|
||||
!macx-xcode: addExclusiveBuilds(debug, Debug, release, Release)
|
||||
} else: fix_output_dirs {
|
||||
debug: \
|
||||
fixExclusiveOutputDirs(debug, release)
|
||||
else: \
|
||||
fixExclusiveOutputDirs(release, debug)
|
||||
!macx-xcode {
|
||||
debug_and_release {
|
||||
addExclusiveBuilds(debug, Debug, release, Release)
|
||||
} else: fix_output_dirs {
|
||||
debug: \
|
||||
fixExclusiveOutputDirs(debug, release)
|
||||
else: \
|
||||
fixExclusiveOutputDirs(release, debug)
|
||||
}
|
||||
} else {
|
||||
# The Xcode generator always generates project files with
|
||||
# debug and release configurations, regardless of whether
|
||||
# or not debug_and_release is active.
|
||||
for(build, $$list(debug release)) {
|
||||
suffix =
|
||||
contains(QT_CONFIG, debug_and_release) {
|
||||
equals(build, debug): \
|
||||
suffix = _debug
|
||||
} else {
|
||||
contains(QT_CONFIG, debug): \
|
||||
suffix = _debug
|
||||
}
|
||||
|
||||
library_suffix_$${build}.name = $$QMAKE_XCODE_LIBRARY_SUFFIX_SETTING
|
||||
library_suffix_$${build}.value = $$suffix
|
||||
library_suffix_$${build}.build = $$build
|
||||
QMAKE_MAC_XCODE_SETTINGS += library_suffix_$${build}
|
||||
|
||||
CONFIG *= xcode_dynamic_library_suffix
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,34 +10,35 @@ check.files =
|
|||
check.path = .
|
||||
|
||||
# If the test ends up in a different directory, we should cd to that directory.
|
||||
# Note that qmake modifies DESTDIR after this file is processed,
|
||||
# therefore, testing DESTDIR for emptiness is not sufficient.
|
||||
# Also note that in debug-and-release mode we don't want to cd into the debug/release
|
||||
# directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
|
||||
# cd foo && release/tst_thing.exe ).
|
||||
MUNGED_DESTDIR=$$DESTDIR
|
||||
MUNGED_TARGET=$$TARGET
|
||||
win32:debug_and_release {
|
||||
contains(DESTDIR,^release$)|contains(DESTDIR,^debug$):MUNGED_DESTDIR=
|
||||
TESTRUN_CWD = $$DESTDIR
|
||||
|
||||
# In debug-and-release mode, the first ../ in TARGET breaks out of the debug/release
|
||||
# subdirectory. However, since make's working directory is already outside of the
|
||||
# debug/release subdirectory, this first ../ should be ignored when deciding if
|
||||
# we have to change directory before running the test.
|
||||
MUNGED_TARGET=$$replace(MUNGED_TARGET,^\\.\\./,)
|
||||
debug_and_release:debug_and_release_target {
|
||||
# But in debug-and-release-target mode we don't want to cd into the debug/release
|
||||
# directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
|
||||
# 'cd foo && release/tst_thing.exe', not 'cd foo/release && tst_thing.exe').
|
||||
|
||||
TESTRUN_CWD ~= s/(release|debug)$//
|
||||
TEST_TARGET_DIR = $$relative_path($$absolute_path($$DESTDIR, $$OUT_PWD), $$absolute_path($$TESTRUN_CWD, $$OUT_PWD))
|
||||
}
|
||||
!isEmpty(MUNGED_DESTDIR):!contains(MUNGED_DESTDIR,^\\./?):check.commands = cd $(DESTDIR) &&
|
||||
contains(MUNGED_TARGET,.*/.*):check.commands = cd $(DESTDIR) &&
|
||||
|
||||
!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD,^\\./?): \
|
||||
check.commands = cd $$system_path($$TESTRUN_CWD) &&
|
||||
|
||||
# Allow for a custom test runner script
|
||||
check.commands += $(TESTRUNNER)
|
||||
|
||||
mac {
|
||||
app_bundle: check.commands += ./$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
|
||||
else: check.commands += ./$(QMAKE_TARGET)
|
||||
unix {
|
||||
isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
|
||||
|
||||
mac:app_bundle: \
|
||||
check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
|
||||
else: \
|
||||
check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
|
||||
} else {
|
||||
# Windows
|
||||
!isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $${TEST_TARGET_DIR}$${QMAKE_DIR_SEP}
|
||||
check.commands += $${TEST_TARGET_DIR}$(TARGET)
|
||||
}
|
||||
else:unix: check.commands += ./$(QMAKE_TARGET)
|
||||
else: check.commands += $(DESTDIR_TARGET)
|
||||
|
||||
# Allow for custom arguments to tests
|
||||
check.commands += $(TESTARGS)
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
linux*:CONFIG = wayland-scanner $$CONFIG
|
||||
|
||||
load(default_pre)
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
|
|||
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
|
||||
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
|
||||
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
|
||||
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
|
||||
QMAKE_CXXFLAGS_CXX11 = -std=c++0x
|
||||
|
||||
QMAKE_INCDIR =
|
||||
|
|
|
|||
|
|
@ -17,10 +17,13 @@ equals(TEMPLATE, app) {
|
|||
# building by calling out to xcodebuild.
|
||||
TEMPLATE = aux
|
||||
|
||||
CONFIG -= have_target qt staticlib dll
|
||||
CONFIG =
|
||||
SOURCES =
|
||||
OBJECTIVE_SOURCES =
|
||||
RESOURCES =
|
||||
INSTALLS =
|
||||
QMAKE_EXTRA_COMPILERS =
|
||||
QMAKE_EXTRA_TARGETS =
|
||||
|
||||
TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj
|
||||
|
||||
|
|
@ -41,6 +44,7 @@ equals(TEMPLATE, app) {
|
|||
|
||||
# And distclean
|
||||
xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR"
|
||||
xcodebuild_distclean.depends = xcodebuild_clean
|
||||
QMAKE_EXTRA_TARGETS += xcodebuild_distclean
|
||||
distclean.depends = xcodebuild_distclean
|
||||
QMAKE_EXTRA_TARGETS += distclean
|
||||
|
|
@ -53,21 +57,11 @@ macx-xcode {
|
|||
QMAKE_MAC_XCODE_SETTINGS += ios_device_family
|
||||
}
|
||||
|
||||
isEmpty(QT_ARCH) {
|
||||
# The iPhoneOS and iPhoneSimulator targets share the same toolchain,
|
||||
# so when configure runs the arch tests it passes the correct sysroot,
|
||||
# but we fail to pick up the architecture since we're not passing -arch
|
||||
# yet. Xcode does not seem to have a way to run the shared toolchain
|
||||
# in a way that will automatically do this (for example xcrun -sdk).
|
||||
contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm
|
||||
else: QT_ARCH = i386 # Simulator
|
||||
}
|
||||
|
||||
# Be more specific about which architecture we're targeting
|
||||
equals(QT_ARCH, arm): \
|
||||
actual_archs = armv7
|
||||
actual_archs = $$QMAKE_IOS_DEVICE_ARCHS
|
||||
else: \
|
||||
actual_archs = $$QT_ARCH
|
||||
actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS
|
||||
|
||||
macx-xcode {
|
||||
QMAKE_XCODE_ARCHS = $$actual_archs
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
load(default_pre)
|
||||
|
||||
# Check for supported Xcode versions
|
||||
lessThan(QMAKE_XCODE_VERSION, "4.3"): \
|
||||
error("This mkspec requires Xcode 4.3 or later")
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
equals(TEMPLATE, app):contains(QT, gui(-private)?) {
|
||||
LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
|
||||
|
||||
lib_name = qios
|
||||
lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
|
||||
LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
|
||||
|
||||
# By marking qt_registerPlatformPlugin as undefined, we ensure that
|
||||
# the plugin.o translation unit is considered for inclusion in
|
||||
# the final binary, which in turn ensures that the plugin's
|
||||
# static initializer is included and run.
|
||||
QMAKE_LFLAGS += -u _qt_registerPlatformPlugin
|
||||
|
||||
# We do link and dependency resolution for the platform plugin
|
||||
# manually, since we know we always need the plugin, so we don't
|
||||
# need to generate an import for it.
|
||||
CONFIG -= import_qpa_plugin
|
||||
|
||||
!no_main_wrapper {
|
||||
# We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash
|
||||
# with the _main we provide that calls UIApplicationMain. We need to make a copy of the
|
||||
# original object file, as ld will not copy over DWARF debug information to the output
|
||||
# file. Instead, it will inject a reference back to the original object file, so when
|
||||
# Xcode runs dsymutil to make the final dSYM file it will still find the debug info
|
||||
# for the object file that provided the original _main. This back-reference has the
|
||||
# interesting side-effect of the debug information still referring to the original
|
||||
# symbol name, so stack-traces will show both our wrapper main and the original
|
||||
# user main as 'main', and adding a symbolic breakpoint for 'main' will break on
|
||||
# both functions. Although a bit weird, it's a good thing, as the user will still be
|
||||
# able to add symbolic breakpoints for 'main', not caring that the symbol is actually
|
||||
# called 'qt_main' now.
|
||||
|
||||
isEmpty(OBJECTS_DIR): \
|
||||
OBJECTS_DIR = .
|
||||
|
||||
!isEmpty(QMAKE_PRE_LINK): \
|
||||
QMAKE_PRE_LINK += ";"
|
||||
|
||||
QMAKE_PRE_LINK += \
|
||||
"for f in $(find $${OBJECTS_DIR} -name '*.o'); do" \
|
||||
"(nm $f | grep -q 'T _main' && cp $f $f.original" \
|
||||
"&& ld -r -alias _main _qt_main -unexported_symbol _main $f.original -o $f)" \
|
||||
"|| true" \
|
||||
"; done"
|
||||
}
|
||||
}
|
||||
|
||||
load(qt)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
load(qt_config)
|
||||
|
||||
isEmpty(QT_ARCH) {
|
||||
# The configure tests are run without QT_ARCH being resolved yet, which
|
||||
# means we fail to pass -arch to the compiler, resulting in broke tests.
|
||||
# As the Xcode toolchain doesn't seem to have a way to auto-detect the
|
||||
# arch based on the SDK, we have to hard-code the arch for configure.
|
||||
contains(QMAKE_MAC_SDK, iphoneos.*): \
|
||||
QT_ARCH = arm
|
||||
else: \ # Simulator
|
||||
QT_ARCH = i386
|
||||
}
|
||||
|
|
@ -10,11 +10,14 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET =
|
|||
QMAKE_IOS_DEPLOYMENT_TARGET = 5.0
|
||||
|
||||
INCLUDEPATH += $$PWD/ios
|
||||
DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG
|
||||
DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG
|
||||
|
||||
# Universal target (iPhone and iPad)
|
||||
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
|
||||
|
||||
QMAKE_IOS_DEVICE_ARCHS = armv7
|
||||
QMAKE_IOS_SIMULATOR_ARCHS = i386
|
||||
|
||||
include(../common/ios.conf)
|
||||
include(../common/gcc-base-mac.conf)
|
||||
include(../common/clang.conf)
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
isEmpty(QMAKE_INFO_PLIST) {
|
||||
plist_template = $$absolute_path(../../$$[QMAKE_XSPEC]/Info.plist.$${TEMPLATE})
|
||||
exists($$plist_template): QMAKE_INFO_PLIST = $$plist_template
|
||||
}
|
||||
|
||||
load(default_post)
|
||||
|
|
@ -4,6 +4,12 @@
|
|||
# OS X + Xcode
|
||||
#
|
||||
|
||||
include(../$$[QMAKE_XSPEC]/qmake.conf)
|
||||
QMAKESPEC = $$dirname(PWD)/$$[QMAKE_XSPEC]
|
||||
|
||||
include($$QMAKESPEC/qmake.conf)
|
||||
|
||||
MAKEFILE_GENERATOR = XCODE
|
||||
|
||||
# The active spec is now the original spec, but we still want
|
||||
# Xcode specific blocks to be triggered.
|
||||
CONFIG += macx-xcode
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevic
|
|||
qabstractfileengine.o qtemporaryfile.o qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o \
|
||||
qvariant.o qvsnprintf.o qlocale.o qlocale_tools.o qlinkedlist.o qnumeric.o \
|
||||
qcryptographichash.o qxmlstream.o qxmlutils.o qlogging.o \
|
||||
qjson.o qjsondocument.o qjsonparser.o qjsonarray.o qjsonobject.o qjsonvalue.o \
|
||||
$(QTOBJS)
|
||||
|
||||
|
||||
|
|
@ -80,6 +81,12 @@ DEPEND_SRC = \
|
|||
$(SOURCE_PATH)/src/corelib/global/qlogging.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \
|
||||
$(SOURCE_PATH)/tools/shared/windows/registry.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjson.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp \
|
||||
$(QTSRCS)
|
||||
|
||||
CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
|
||||
|
|
@ -93,7 +100,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
|
|||
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
|
||||
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
|
||||
-DQT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
-DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY
|
||||
|
||||
CXXFLAGS = $(EXTRA_CXXFLAGS) $(CPPFLAGS)
|
||||
|
||||
|
|
@ -385,4 +392,22 @@ qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
|
|||
registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
|
||||
|
||||
qjson.o: $(SOURCE_PATH)/src/corelib/json/qjson.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjson.cpp
|
||||
|
||||
qjsondocument.o: $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp
|
||||
|
||||
qjsonparser.o: $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp
|
||||
|
||||
qjsonarray.o: $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp
|
||||
|
||||
qjsonobject.o: $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp
|
||||
|
||||
qjsonvalue.o: $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ CFLAGS_BARE = -c -Fo./ \
|
|||
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
|
||||
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
|
||||
-DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
-DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY
|
||||
CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS) $(EXTRA_CPPFLAGS)
|
||||
|
||||
CXXFLAGS_BARE = $(CFLAGS_BARE)
|
||||
|
|
@ -120,7 +120,13 @@ QTOBJS= \
|
|||
qxmlstream.obj \
|
||||
qxmlutils.obj \
|
||||
qnumeric.obj \
|
||||
qlogging.obj
|
||||
qlogging.obj \
|
||||
qjson.obj \
|
||||
qjsondocument.obj \
|
||||
qjsonparser.obj \
|
||||
qjsonarray.obj \
|
||||
qjsonobject.obj \
|
||||
qjsonvalue.obj
|
||||
|
||||
first all: qmake.exe
|
||||
|
||||
|
|
@ -207,5 +213,8 @@ qmake_pch.obj:
|
|||
{$(SOURCE_PATH)\src\corelib\xml}.cpp{}.obj::
|
||||
$(CXX) $(CXXFLAGS) $<
|
||||
|
||||
{$(SOURCE_PATH)\src\corelib\json}.cpp{}.obj::
|
||||
$(CXX) $(CXXFLAGS) $<
|
||||
|
||||
{$(SOURCE_PATH)\tools\shared\windows}.cpp{}.obj::
|
||||
$(CXX) $(CXXFLAGS) $<
|
||||
|
|
|
|||
|
|
@ -301,6 +301,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
|||
QString defaultConfig;
|
||||
for(int as_release = 0; as_release < 2; as_release++)
|
||||
{
|
||||
QString configName = (as_release ? "Release" : "Debug");
|
||||
|
||||
QMap<QString, QString> settings;
|
||||
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
|
||||
if(as_release)
|
||||
|
|
@ -311,6 +313,12 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
|||
const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS");
|
||||
for(int i = 0; i < l.size(); ++i) {
|
||||
ProString name = l.at(i);
|
||||
const ProKey buildKey(name + ".build");
|
||||
if (!project->isEmpty(buildKey)) {
|
||||
const QString build = project->values(buildKey).first().toQString();
|
||||
if (build.toLower() != configName.toLower())
|
||||
continue;
|
||||
}
|
||||
const ProKey nkey(name + ".name");
|
||||
if (!project->isEmpty(nkey))
|
||||
name = project->first(nkey);
|
||||
|
|
@ -319,10 +327,9 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
|||
}
|
||||
}
|
||||
|
||||
QString name = (as_release ? "Release" : "Debug");
|
||||
if (project->isActiveConfig("debug") != (bool)as_release)
|
||||
defaultConfig = name;
|
||||
QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + name);
|
||||
defaultConfig = configName;
|
||||
QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + configName);
|
||||
project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS").append(key);
|
||||
t << "\t\t" << key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
|
||||
|
|
@ -330,7 +337,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
|||
for (QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
|
||||
t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
|
||||
t << "\t\t\t};\n"
|
||||
<< "\t\t\t" << writeSettings("name", name) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", configName) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {\n"
|
||||
|
|
@ -867,6 +874,20 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
|
||||
opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData());
|
||||
remove = true;
|
||||
|
||||
if (project->isActiveConfig("xcode_dynamic_library_suffix")) {
|
||||
QString suffixSetting = project->first("QMAKE_XCODE_LIBRARY_SUFFIX_SETTING").toQString();
|
||||
if (!suffixSetting.isEmpty()) {
|
||||
QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
|
||||
suffixSetting = "$(" + suffixSetting + ")";
|
||||
if (!librarySuffix.isEmpty()) {
|
||||
library = library.replace(librarySuffix, suffixSetting);
|
||||
name = name.remove(librarySuffix);
|
||||
} else {
|
||||
library = library.replace(name, name + suffixSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -998,6 +1019,27 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
if (!project->isEmpty("QMAKE_PRE_LINK")) {
|
||||
QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE");
|
||||
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
|
||||
// The build phases are not executed in the order they are defined, but by their
|
||||
// resolved dependenices, so we have to ensure that this phase is run after the
|
||||
// compilation phase, and before the link phase. Making the phase depend on all the
|
||||
// object files, and "write" to the list of files to link achieves that.
|
||||
<< "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/*" + Option::obj_ext), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_PRE_LINK")) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
//LIBRARY BUILDPHASE
|
||||
if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) {
|
||||
tmp = project->values("QMAKE_PBX_LIBRARIES");
|
||||
|
|
@ -1023,6 +1065,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
if (!project->isEmpty("QMAKE_POST_LINK")) {
|
||||
QString phase_key = keyFor("QMAKE_PBX_POSTLINK_BUILDPHASE");
|
||||
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
|
||||
// The build phases are not executed in the order they are defined, but by their
|
||||
// resolved dependenices, so we have to ensure the phase is run after linking.
|
||||
<< "\t\t\t" << writeSettings("inputPaths", ProStringList("$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
if (!project->isEmpty("DESTDIR")) {
|
||||
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
|
||||
QString destDir = project->first("DESTDIR").toQString();
|
||||
|
|
@ -1244,6 +1304,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
QString defaultConfig;
|
||||
for(int as_release = 0; as_release < 2; as_release++)
|
||||
{
|
||||
QString configName = (as_release ? "Release" : "Debug");
|
||||
|
||||
QMap<QString, QString> settings;
|
||||
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
|
||||
settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
|
||||
|
|
@ -1255,6 +1317,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS");
|
||||
for(int i = 0; i < l.size(); ++i) {
|
||||
ProString name = l.at(i);
|
||||
const ProKey buildKey(name + ".build");
|
||||
if (!project->isEmpty(buildKey)) {
|
||||
const QString build = project->values(buildKey).first().toQString();
|
||||
if (build.toLower() != configName.toLower())
|
||||
continue;
|
||||
}
|
||||
const QString value = project->values(ProKey(name + ".value")).join(QString(Option::field_sep));
|
||||
const ProKey nkey(name + ".name");
|
||||
if (!project->isEmpty(nkey))
|
||||
|
|
@ -1271,11 +1339,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString()));
|
||||
}
|
||||
|
||||
QString name = (as_release ? "Release" : "Debug");
|
||||
if (project->isActiveConfig("debug") != (bool)as_release)
|
||||
defaultConfig = name;
|
||||
defaultConfig = configName;
|
||||
for (int i = 0; i < buildConfigGroups.size(); i++) {
|
||||
QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i));
|
||||
QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + configName + buildConfigGroups.at(i));
|
||||
project->values(ProKey("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i))).append(key);
|
||||
t << "\t\t" << key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
|
||||
|
|
@ -1429,7 +1496,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
}
|
||||
t << "\t\t\t};\n"
|
||||
<< "\t\t\t" << writeSettings("name", name) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", configName) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3240,7 +3240,8 @@ MakefileGenerator::writePkgConfigFile()
|
|||
}
|
||||
}
|
||||
}
|
||||
t << var << "=" << val << endl;
|
||||
if (!val.isEmpty())
|
||||
t << var << "=" << val << endl;
|
||||
}
|
||||
|
||||
t << endl;
|
||||
|
|
@ -3331,8 +3332,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt
|
|||
{
|
||||
QString ret;
|
||||
if (project->isEmpty(replace_rule)
|
||||
|| project->isActiveConfig("no_sed_meta_install")
|
||||
|| project->isEmpty("QMAKE_STREAM_EDITOR")) {
|
||||
|| project->isActiveConfig("no_sed_meta_install")) {
|
||||
ret += "-$(INSTALL_FILE) \"" + src + "\" \"" + dst + "\"";
|
||||
} else {
|
||||
ret += "-$(SED)";
|
||||
|
|
|
|||
|
|
@ -106,20 +106,8 @@ UnixMakefileGenerator::init()
|
|||
return; /* subdirs is done */
|
||||
}
|
||||
|
||||
//If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
|
||||
if(!project->isEmpty("TARGET")) {
|
||||
if (!project->isEmpty("TARGET"))
|
||||
project->values("TARGET") = escapeFilePaths(project->values("TARGET"));
|
||||
ProString targ = unescapeFilePath(project->first("TARGET"));
|
||||
int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep));
|
||||
if(slsh != -1) {
|
||||
if(project->isEmpty("DESTDIR"))
|
||||
project->values("DESTDIR").append("");
|
||||
else if(project->first("DESTDIR").right(1) != Option::dir_sep)
|
||||
project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep);
|
||||
project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1));
|
||||
project->values("TARGET") = ProStringList(targ.mid(slsh+1));
|
||||
}
|
||||
}
|
||||
|
||||
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
|
||||
project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR");
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
|
|||
if (!qmake_setpwd(dir))
|
||||
fprintf(stderr, "Cannot find directory: %s", dir.toLatin1().constData());
|
||||
}
|
||||
Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(fi.absoluteFilePath()));
|
||||
Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(dir));
|
||||
if (tmp_proj.read(fn)) {
|
||||
// Check if all requirements are fulfilled
|
||||
if (!tmp_proj.isEmpty("QMAKE_FAILED_REQUIREMENTS")) {
|
||||
|
|
|
|||
|
|
@ -274,20 +274,6 @@ Win32MakefileGenerator::processPrlFiles()
|
|||
|
||||
void Win32MakefileGenerator::processVars()
|
||||
{
|
||||
//If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
|
||||
if(!project->isEmpty("TARGET")) {
|
||||
ProString targ = project->first("TARGET");
|
||||
int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep));
|
||||
if(slsh != -1) {
|
||||
if(project->isEmpty("DESTDIR"))
|
||||
project->values("DESTDIR").append("");
|
||||
else if(project->first("DESTDIR").right(1) != Option::dir_sep)
|
||||
project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep);
|
||||
project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1));
|
||||
project->values("TARGET") = ProStringList(targ.mid(slsh+1));
|
||||
}
|
||||
}
|
||||
|
||||
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
|
||||
if (project->isEmpty("QMAKE_PROJECT_NAME"))
|
||||
project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET");
|
||||
|
|
@ -315,6 +301,8 @@ void Win32MakefileGenerator::processVars()
|
|||
project->values("QMAKE_COPY_FILE").append("$(COPY)");
|
||||
if(project->isEmpty("QMAKE_COPY_DIR"))
|
||||
project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i");
|
||||
if (project->isEmpty("QMAKE_STREAM_EDITOR"))
|
||||
project->values("QMAKE_STREAM_EDITOR").append("$(QMAKE) -install sed");
|
||||
if(project->isEmpty("QMAKE_INSTALL_FILE"))
|
||||
project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)");
|
||||
if(project->isEmpty("QMAKE_INSTALL_PROGRAM"))
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@
|
|||
#include <qset.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextstream.h>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
# include <qjsondocument.h>
|
||||
# include <qjsonobject.h>
|
||||
# include <qjsonarray.h>
|
||||
#endif
|
||||
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||
# include <qthreadpool.h>
|
||||
#endif
|
||||
|
|
@ -101,7 +106,7 @@ enum TestFunc {
|
|||
T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
|
||||
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
|
||||
T_DEFINED, T_CONTAINS, T_INFILE,
|
||||
T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
|
||||
T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
|
||||
T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE
|
||||
};
|
||||
|
||||
|
|
@ -178,6 +183,9 @@ void QMakeEvaluator::initFunctionStatics()
|
|||
{ "infile", T_INFILE },
|
||||
{ "count", T_COUNT },
|
||||
{ "isEmpty", T_ISEMPTY },
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
{ "parseJson", T_PARSE_JSON },
|
||||
#endif
|
||||
{ "load", T_LOAD },
|
||||
{ "include", T_INCLUDE },
|
||||
{ "debug", T_DEBUG },
|
||||
|
|
@ -286,6 +294,75 @@ quoteValue(const ProString &val)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map);
|
||||
|
||||
static void insertJsonKeyValue(const QString &key, const QStringList &values, ProValueMap *map)
|
||||
{
|
||||
map->insert(ProKey(key), ProStringList(values));
|
||||
}
|
||||
|
||||
static void addJsonArray(const QJsonArray &array, const QString &keyPrefix, ProValueMap *map)
|
||||
{
|
||||
QStringList keys;
|
||||
for (int i = 0; i < array.count(); ++i) {
|
||||
keys.append(QString::number(i));
|
||||
addJsonValue(array.at(i), keyPrefix + QString::number(i), map);
|
||||
}
|
||||
insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map);
|
||||
}
|
||||
|
||||
static void addJsonObject(const QJsonObject &object, const QString &keyPrefix, ProValueMap *map)
|
||||
{
|
||||
foreach (const QString &key, object.keys())
|
||||
addJsonValue(object.value(key), keyPrefix + key, map);
|
||||
|
||||
insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), object.keys(), map);
|
||||
}
|
||||
|
||||
static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map)
|
||||
{
|
||||
switch (value.type()) {
|
||||
case QJsonValue::Bool:
|
||||
insertJsonKeyValue(keyPrefix, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")), map);
|
||||
break;
|
||||
case QJsonValue::Double:
|
||||
insertJsonKeyValue(keyPrefix, QStringList() << QString::number(value.toDouble()), map);
|
||||
break;
|
||||
case QJsonValue::String:
|
||||
insertJsonKeyValue(keyPrefix, QStringList() << value.toString(), map);
|
||||
break;
|
||||
case QJsonValue::Array:
|
||||
addJsonArray(value.toArray(), keyPrefix + QLatin1Char('.'), map);
|
||||
break;
|
||||
case QJsonValue::Object:
|
||||
addJsonObject(value.toObject(), keyPrefix + QLatin1Char('.'), map);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value)
|
||||
{
|
||||
QJsonDocument document = QJsonDocument::fromJson(json);
|
||||
if (document.isNull())
|
||||
return QMakeEvaluator::ReturnFalse;
|
||||
|
||||
QString currentKey = into + QLatin1Char('.');
|
||||
|
||||
// top-level item is either an array or object
|
||||
if (document.isArray())
|
||||
addJsonArray(document.array(), currentKey, value);
|
||||
else if (document.isObject())
|
||||
addJsonObject(document.object(), currentKey, value);
|
||||
else
|
||||
return QMakeEvaluator::ReturnFalse;
|
||||
|
||||
return QMakeEvaluator::ReturnTrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
QMakeEvaluator::VisitReturn
|
||||
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
||||
const QString &contents)
|
||||
|
|
@ -1278,6 +1355,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||
m_valuemapStack.top()[var] = statics.fakeValue;
|
||||
return ReturnTrue;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
case T_PARSE_JSON: {
|
||||
if (args.count() != 2) {
|
||||
evalError(fL1S("parseJson(variable, into) requires two arguments."));
|
||||
return ReturnFalse;
|
||||
}
|
||||
|
||||
QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8();
|
||||
QString parseInto = args.at(1).toQString(m_tmp2);
|
||||
return parseJsonInto(json, parseInto, &m_valuemapStack.top());
|
||||
}
|
||||
#endif
|
||||
case T_INCLUDE: {
|
||||
if (args.count() < 1 || args.count() > 3) {
|
||||
evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ void QMakeEvaluator::initStatics()
|
|||
statics.strhost_build = QLatin1String("host_build");
|
||||
statics.strTEMPLATE = ProKey("TEMPLATE");
|
||||
statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM");
|
||||
statics.strQMAKESPEC = ProKey("QMAKESPEC");
|
||||
#ifdef PROEVALUATOR_FULL
|
||||
statics.strREQUIRES = ProKey("REQUIRES");
|
||||
#endif
|
||||
|
|
@ -939,6 +940,12 @@ void QMakeEvaluator::visitProVariable(
|
|||
setTemplate();
|
||||
else if (varName == statics.strQMAKE_PLATFORM)
|
||||
m_featureRoots = 0;
|
||||
else if (varName == statics.strQMAKESPEC) {
|
||||
if (!values(varName).isEmpty()) {
|
||||
m_qmakespec = values(varName).first().toQString();
|
||||
m_featureRoots = 0;
|
||||
}
|
||||
}
|
||||
#ifdef PROEVALUATOR_FULL
|
||||
else if (varName == statics.strREQUIRES)
|
||||
checkRequirements(values(varName));
|
||||
|
|
@ -1160,7 +1167,7 @@ bool QMakeEvaluator::loadSpecInternal()
|
|||
m_qmakespec = orig_spec.toQString();
|
||||
# endif
|
||||
#endif
|
||||
valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec);
|
||||
valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec);
|
||||
m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
|
||||
// This also ensures that m_featureRoots is valid.
|
||||
if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
|
||||
|
|
@ -1271,6 +1278,14 @@ void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
|||
}
|
||||
}
|
||||
|
||||
void QMakeEvaluator::applyExtraConfigs()
|
||||
{
|
||||
if (m_extraConfigs.isEmpty())
|
||||
return;
|
||||
|
||||
evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
|
||||
}
|
||||
|
||||
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures()
|
||||
{
|
||||
QSet<QString> processed;
|
||||
|
|
@ -1365,10 +1380,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
|||
loadDefaults();
|
||||
}
|
||||
|
||||
for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
|
||||
it != m_extraVars.constEnd(); ++it)
|
||||
m_valuemapStack.first().insert(it.key(), it.value());
|
||||
|
||||
VisitReturn vr;
|
||||
|
||||
m_handler->aboutToEval(currentProFile(), pro, type);
|
||||
|
|
@ -1377,14 +1388,23 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
|||
if (flags & LoadPreFiles) {
|
||||
setupProject();
|
||||
|
||||
for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
|
||||
it != m_extraVars.constEnd(); ++it)
|
||||
m_valuemapStack.first().insert(it.key(), it.value());
|
||||
|
||||
// In case default_pre needs to make decisions based on the current
|
||||
// build pass configuration.
|
||||
applyExtraConfigs();
|
||||
|
||||
if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError)
|
||||
goto failed;
|
||||
|
||||
evaluateCommand(m_option->precmds, fL1S("(command line)"));
|
||||
if (!m_option->precmds.isEmpty()) {
|
||||
evaluateCommand(m_option->precmds, fL1S("(command line)"));
|
||||
|
||||
// After user configs, to override them
|
||||
if (!m_extraConfigs.isEmpty())
|
||||
evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
|
||||
// Again, after user configs, to override them
|
||||
applyExtraConfigs();
|
||||
}
|
||||
}
|
||||
|
||||
debugMsg(1, "visiting file %s", qPrintable(pro->fileName()));
|
||||
|
|
@ -1398,8 +1418,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
|||
// Again, to ensure the project does not mess with us.
|
||||
// Specifically, do not allow a project to override debug/release within a
|
||||
// debug_and_release build pass - it's too late for that at this point anyway.
|
||||
if (!m_extraConfigs.isEmpty())
|
||||
evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
|
||||
applyExtraConfigs();
|
||||
|
||||
if ((vr = evaluateFeatureFile(QLatin1String("default_post.prf"))) == ReturnError)
|
||||
goto failed;
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ public:
|
|||
void initFrom(const QMakeEvaluator &other);
|
||||
void setupProject();
|
||||
void evaluateCommand(const QString &cmds, const QString &where);
|
||||
void applyExtraConfigs();
|
||||
VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
|
||||
LoadFlags flags);
|
||||
VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ struct QMakeStatics {
|
|||
QString strhost_build;
|
||||
ProKey strTEMPLATE;
|
||||
ProKey strQMAKE_PLATFORM;
|
||||
ProKey strQMAKESPEC;
|
||||
#ifdef PROEVALUATOR_FULL
|
||||
ProKey strREQUIRES;
|
||||
#endif
|
||||
|
|
|
|||
128
qmake/main.cpp
128
qmake/main.cpp
|
|
@ -57,6 +57,128 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
struct SedSubst {
|
||||
QRegExp from;
|
||||
QString to;
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(SedSubst, Q_MOVABLE_TYPE);
|
||||
|
||||
static int doSed(int argc, char **argv)
|
||||
{
|
||||
QVector<SedSubst> substs;
|
||||
QList<const char *> inFiles;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-e")) {
|
||||
if (++i == argc) {
|
||||
fprintf(stderr, "Error: sed option -e requires an argument\n");
|
||||
return 3;
|
||||
}
|
||||
QString cmd = QString::fromLocal8Bit(argv[i]);
|
||||
for (int j = 0; j < cmd.length(); j++) {
|
||||
QChar c = cmd.at(j);
|
||||
if (c.isSpace())
|
||||
continue;
|
||||
if (c != QLatin1Char('s')) {
|
||||
fprintf(stderr, "Error: unrecognized sed command '%c'\n", c.toLatin1());
|
||||
return 3;
|
||||
}
|
||||
QChar sep = ++j < cmd.length() ? cmd.at(j) : QChar();
|
||||
bool escaped = false;
|
||||
int phase = 1;
|
||||
QStringList phases;
|
||||
QString curr;
|
||||
while (++j < cmd.length()) {
|
||||
c = cmd.at(j);
|
||||
if (!escaped) {
|
||||
if (c == QLatin1Char(';'))
|
||||
break;
|
||||
if (c == QLatin1Char('\\')) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (c == sep) {
|
||||
phase++;
|
||||
phases << curr;
|
||||
curr.clear();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (phase == 1
|
||||
&& (c == QLatin1Char('+') || c == QLatin1Char('?')
|
||||
|| c == QLatin1Char('{') || c == QLatin1Char('}')
|
||||
|| c == QLatin1Char('(') || c == QLatin1Char(')'))) {
|
||||
// translate sed rx to QRegExp
|
||||
escaped ^= 1;
|
||||
}
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
curr += QLatin1Char('\\');
|
||||
}
|
||||
curr += c;
|
||||
}
|
||||
if (escaped) {
|
||||
fprintf(stderr, "Error: unterminated escape sequence in sed s command\n");
|
||||
return 3;
|
||||
}
|
||||
if (phase != 3) {
|
||||
fprintf(stderr, "Error: sed s command requires three arguments (%d, %c, %s)\n", phase, sep.toLatin1(), qPrintable(curr));
|
||||
return 3;
|
||||
}
|
||||
if (curr != QLatin1String("g")) {
|
||||
fprintf(stderr, "Error: sed s command must be used with the g option (only)\n");
|
||||
return 3;
|
||||
}
|
||||
SedSubst subst;
|
||||
subst.from = QRegExp(phases.at(0));
|
||||
subst.to = phases.at(1);
|
||||
substs << subst;
|
||||
}
|
||||
} else if (argv[i][0] == '-' && argv[i][1] != 0) {
|
||||
fprintf(stderr, "Error: unrecognized sed option '%s'\n", argv[i]);
|
||||
return 3;
|
||||
} else {
|
||||
inFiles << argv[i];
|
||||
}
|
||||
}
|
||||
if (inFiles.isEmpty())
|
||||
inFiles << "-";
|
||||
foreach (const char *inFile, inFiles) {
|
||||
FILE *f;
|
||||
if (!strcmp(inFile, "-")) {
|
||||
f = stdin;
|
||||
} else if (!(f = fopen(inFile, "r"))) {
|
||||
perror(inFile);
|
||||
return 1;
|
||||
}
|
||||
QTextStream is(f);
|
||||
while (!is.atEnd()) {
|
||||
QString line = is.readLine();
|
||||
for (int i = 0; i < substs.size(); i++)
|
||||
line.replace(substs.at(i).from, substs.at(i).to);
|
||||
puts(qPrintable(line));
|
||||
}
|
||||
if (f != stdin)
|
||||
fclose(f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int doInstall(int argc, char **argv)
|
||||
{
|
||||
if (!argc) {
|
||||
fprintf(stderr, "Error: -install requires further arguments\n");
|
||||
return 3;
|
||||
}
|
||||
if (!strcmp(argv[0], "sed"))
|
||||
return doSed(argc - 1, argv + 1);
|
||||
fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
/* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
|
||||
is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
|
||||
cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
|
||||
|
|
@ -85,6 +207,12 @@ int runQMake(int argc, char **argv)
|
|||
// This is particularly important for things like QtCreator and scripted builds.
|
||||
setvbuf(stdout, (char *)NULL, _IONBF, 0);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Workaround for inferior/missing command line tools on Windows: make our own!
|
||||
if (argc >= 2 && !strcmp(argv[1], "-install"))
|
||||
return doInstall(argc - 2, argv + 2);
|
||||
#endif
|
||||
|
||||
QMakeVfs vfs;
|
||||
Option::vfs = &vfs;
|
||||
QMakeGlobals globals;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,13 @@ bootstrap { #Qt code
|
|||
qvsnprintf.cpp \
|
||||
qxmlstream.cpp \
|
||||
qxmlutils.cpp \
|
||||
qlogging.cpp
|
||||
qlogging.cpp \
|
||||
qjson.cpp \
|
||||
qjsondocument.cpp \
|
||||
qjsonparser.cpp \
|
||||
qjsonarray.cpp \
|
||||
qjsonobject.cpp \
|
||||
qjsonvalue.cpp
|
||||
|
||||
HEADERS+= \
|
||||
qbitarray.h \
|
||||
|
|
@ -126,7 +132,14 @@ bootstrap { #Qt code
|
|||
quuid.h \
|
||||
qvector.h \
|
||||
qxmlstream.h \
|
||||
qxmlutils.h
|
||||
qxmlutils.h \
|
||||
qjson.h \
|
||||
qjsondocument.h \
|
||||
qjsonparser.h \
|
||||
qjsonwriter.h \
|
||||
qjsonarray.h \
|
||||
qjsonobject.h \
|
||||
qjsonvalue.h
|
||||
|
||||
unix {
|
||||
SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ VPATH += $$QT_SOURCE_TREE/src/corelib/global \
|
|||
$$QT_SOURCE_TREE/src/corelib/plugin \
|
||||
$$QT_SOURCE_TREE/src/corelib/xml \
|
||||
$$QT_SOURCE_TREE/src/corelib/io \
|
||||
$$QT_SOURCE_TREE/src/corelib/json \
|
||||
$$QT_SOURCE_TREE/tools/shared/windows
|
||||
|
||||
INCLUDEPATH += . \
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
|
|||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
#else
|
||||
return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@
|
|||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:value="@string/repository" android:name="android.app.repository"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
|
||||
<meta-data android:value="@string/app_lib_name" android:name="android.app.lib_name"/>
|
||||
<!-- Deploy Qt libs as part of package -->
|
||||
<meta-data android:value="1" android:name="android.app.bundle_local_qt_libs"/>
|
||||
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||
<!-- Run with local libs -->
|
||||
<meta-data android:value="1" android:name="android.app.use_local_qt_libs"/>
|
||||
<meta-data android:value="/data/local/tmp/qt/" android:name="android.app.libs_prefix"/>
|
||||
<meta-data android:value="@string/local_libs" android:name="android.app.load_local_libs"/>
|
||||
<meta-data android:value="@string/local_jars" android:name="android.app.load_local_jars"/>
|
||||
<meta-data android:value="@string/init_classes" android:name="android.app.static_init_classes"/>
|
||||
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
|
||||
<!-- Messages maps -->
|
||||
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
|
||||
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
<array name="qt_sources">
|
||||
<item>https://download.qt-project.org/ministro/android/qt5/latest</item>
|
||||
</array>
|
||||
<string name="repository">default</string>
|
||||
|
||||
<!-- The following is handled automatically by the deployment tool. It should
|
||||
not be edited manually. -->
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<string name="app_name"><!-- %%INSERT_APP_NAME%% --></string>
|
||||
<string name="app_lib_name"><!-- %%INSERT_APP_LIB_NAME%% --></string>
|
||||
<string name="local_libs"><!-- %%INSERT_LOCAL_LIBS%% --></string>
|
||||
<string name="local_jars"><!-- %%INSERT_LOCAL_JARS%% --></string>
|
||||
<string name="init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
|
||||
|
||||
<string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string>
|
||||
<string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string>
|
||||
|
|
|
|||
|
|
@ -489,6 +489,14 @@ public class QtActivity extends Activity
|
|||
+ "\tQML2_IMPORT_PATH=" + localPrefix + "/qml"
|
||||
+ "\tQML_IMPORT_PATH=" + localPrefix + "/imports"
|
||||
+ "\tQT_PLUGIN_PATH=" + localPrefix + "/plugins");
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent != null) {
|
||||
String parameters = intent.getStringExtra("applicationArguments");
|
||||
if (parameters != null)
|
||||
loaderParams.putString(APPLICATION_PARAMETERS_KEY, parameters.replace(' ', '\t'));
|
||||
}
|
||||
|
||||
loadApplication(loaderParams);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ index 610a5ef..95a6961 100644
|
|||
+#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
+ return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
+#else
|
||||
+ return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
+ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,14 +106,6 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve
|
|||
if (u < 0x0800) {
|
||||
*cursor++ = 0xc0 | ((uchar) (u >> 6));
|
||||
} else {
|
||||
// is it one of the Unicode non-characters?
|
||||
if (QChar::isNonCharacter(u)) {
|
||||
*cursor++ = replacement;
|
||||
++ch;
|
||||
++invalid;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (QChar::requiresSurrogates(u)) {
|
||||
*cursor++ = 0xf0 | ((uchar) (u >> 18));
|
||||
*cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
|
||||
|
|
@ -180,15 +172,14 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
|
|||
--need;
|
||||
if (!need) {
|
||||
// utf-8 bom composes into 0xfeff code point
|
||||
bool nonCharacter;
|
||||
if (!headerdone && uc == 0xfeff) {
|
||||
// don't do anything, just skip the BOM
|
||||
} else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
|
||||
} else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
|
||||
// surrogate pair
|
||||
Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
|
||||
*qch++ = QChar::highSurrogate(uc);
|
||||
*qch++ = QChar::lowSurrogate(uc);
|
||||
} else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) {
|
||||
} else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
|
||||
// error: overlong sequence, UTF16 surrogate or non-character
|
||||
*qch++ = replacement;
|
||||
++invalid;
|
||||
|
|
|
|||
|
|
@ -273,3 +273,33 @@ QString onlyLetters(const QString &in)
|
|||
return out;
|
||||
}
|
||||
//! [23]
|
||||
|
||||
//! [24]
|
||||
QVector<int> a, b;
|
||||
a.resize(100000); // make a big vector filled with 0.
|
||||
|
||||
QVector<int>::iterator i = a.begin();
|
||||
// WRONG way of using the iterator i:
|
||||
b = a;
|
||||
/*
|
||||
Now we should be careful with iterator i since it will point to shared data
|
||||
If we do *i = 4 then we would change the shared instance (both vectors)
|
||||
The behavior differs from STL containers. Avoid doing such things in Qt.
|
||||
*/
|
||||
|
||||
a[0] = 5;
|
||||
/*
|
||||
Container a is now detached from the shared data,
|
||||
and even though i was an iterator from the container a, it now works as an iterator in b.
|
||||
Here the situation is that (*i) == 0.
|
||||
*/
|
||||
|
||||
b.clear(); // Now the iterator i is completely invalid.
|
||||
|
||||
int j = *i; // Undefined behavior!
|
||||
/*
|
||||
The data from b (which i pointed to) is gone.
|
||||
This would be well-defined with STL containers (and (*i) == 5),
|
||||
but with QVector this is likely to crash.
|
||||
*/
|
||||
//! [24]
|
||||
|
|
|
|||
|
|
@ -67,24 +67,45 @@ QList<UsbEntry> usbEntries() {
|
|||
return entries;
|
||||
}
|
||||
|
||||
void main(int argc, char *argv[])
|
||||
//![20]
|
||||
void myCategoryFilter(QLoggingCategory *);
|
||||
//![20]
|
||||
|
||||
//![21]
|
||||
QLoggingCategory::CategoryFilter oldCategoryFilter;
|
||||
|
||||
void myCategoryFilter(QLoggingCategory *category)
|
||||
{
|
||||
// configure qt.driver.usb category here, otherwise forward to to default filter.
|
||||
if (qstrcmp(category->categoryName(), "qt.driver.usb") == 0)
|
||||
category->setEnabled(QtDebugMsg, true);
|
||||
else
|
||||
oldCategoryFilter(category);
|
||||
}
|
||||
//![21]
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
//![2]
|
||||
// don't run the expensive code if the string won't print
|
||||
if (QT_DRIVER_USB().isDebugEnabled()) {
|
||||
QStringList items;
|
||||
foreach (const UsbEntry &entry, usbEntries())
|
||||
items << QString("%1 (%2)").arg(entry.id, entry.classtype);
|
||||
qCDebug(QT_DRIVER_USB) << "devices: " << items;
|
||||
}
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("qt.driver.usb.debug=true"));
|
||||
//![2]
|
||||
|
||||
//![22]
|
||||
|
||||
// ...
|
||||
oldCategoryFilter = QLoggingCategory::installFilter(myCategoryFilter);
|
||||
//![22]
|
||||
|
||||
//![3]
|
||||
qSetMessagePattern("%{category} %{message}");
|
||||
//![3]
|
||||
|
||||
//![4]
|
||||
// usbEntries() will only be called if QT_DRIVER_USB category is enabled
|
||||
qCDebug(QT_DRIVER_USB) << "devices: " << usbEntries();
|
||||
//![3]
|
||||
//![4]
|
||||
|
||||
{
|
||||
//![10]
|
||||
|
|
@ -106,8 +127,7 @@ void main(int argc, char *argv[])
|
|||
qCCritical(category) << "a critical message";
|
||||
//![12]
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//![20]
|
||||
void myCategoryFilter(QLoggingCategory *);
|
||||
//![20]
|
||||
|
|
|
|||
|
|
@ -533,10 +533,18 @@
|
|||
This problem doesn't occur with functions that return a const or
|
||||
non-const reference to a container.
|
||||
|
||||
\section3 Implicit sharing iterator problem
|
||||
|
||||
\l{Implicit sharing} has another consequence on STL-style
|
||||
iterators: You must not take a copy of a container while
|
||||
non-const iterators are active on that container. Java-style
|
||||
iterators don't suffer from that limitation.
|
||||
iterators: you should avoid copying a container while
|
||||
iterators are active on that container. The iterators
|
||||
point to an internal structure, and if you copy a container
|
||||
you should be very careful with your iterators. E.g:
|
||||
|
||||
\snippet code/doc_src_containers.cpp 24
|
||||
|
||||
The above example only shows a problem with QVector, but
|
||||
the problem exists for all the implicitly shared Qt containers.
|
||||
|
||||
\keyword foreach
|
||||
\section1 The foreach Keyword
|
||||
|
|
|
|||
|
|
@ -89,9 +89,12 @@
|
|||
of data. Objects can easily be assigned, sent as function arguments,
|
||||
and returned from functions.
|
||||
|
||||
Implicit sharing takes place behind the scenes; the programmer
|
||||
does not need to worry about it. Even in multithreaded
|
||||
applications, implicit sharing takes place, as explained in
|
||||
Implicit sharing mostly takes place behind the scenes;
|
||||
the programmer rarely needs to worry about it. However, Qt's
|
||||
container iterators have different behavior than those from
|
||||
the STL. Read \l{Implicit sharing iterator problem}.
|
||||
|
||||
In multithreaded applications, implicit sharing takes place, as explained in
|
||||
\l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes}
|
||||
{Threads and Implicitly Shared Classes}.
|
||||
|
||||
|
|
@ -105,9 +108,10 @@
|
|||
greater than one. (This is often called \e {copy-on-write} or
|
||||
\e {value semantics}.)
|
||||
|
||||
An implicitly shared class has total control of its internal data. In
|
||||
An implicitly shared class has control of its internal data. In
|
||||
any member functions that modify its data, it automatically detaches
|
||||
before modifying the data.
|
||||
before modifying the data. Notice, however, the special case with
|
||||
container iterators; see \l{Implicit sharing iterator problem}.
|
||||
|
||||
The QPen class, which uses implicit sharing, detaches from the shared
|
||||
data in all member functions that change the internal data.
|
||||
|
|
@ -133,9 +137,9 @@
|
|||
In this example, \c p1 and \c p2 share data until QPainter::begin()
|
||||
is called for \c p2, because painting a pixmap will modify it.
|
||||
|
||||
\warning Do not copy an implicitly shared container (QMap,
|
||||
QVector, etc.) while you are iterating over it using an non-const
|
||||
\l{STL-style iterators}{STL-style iterator}.
|
||||
\warning Be careful with copying an implicitly shared container
|
||||
(QMap, QVector, etc.) while you use
|
||||
\l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}.
|
||||
|
||||
\keyword implicitly shared classes
|
||||
\annotatedlist shared
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
/*!
|
||||
\page signalsandslots.html
|
||||
\title Signals & Slots
|
||||
\keyword Signals and Slots
|
||||
\ingroup qt-basic-concepts
|
||||
\brief An overview of Qt's signals and slots inter-object
|
||||
communication mechanism.
|
||||
|
|
|
|||
|
|
@ -199,31 +199,6 @@
|
|||
still important.
|
||||
On Linux, Valgrind and Helgrind can help detect threading errors.
|
||||
|
||||
The anatomy of QThread is quite interesting:
|
||||
|
||||
\list
|
||||
\li QThread does not live in the new thread where \l{QThread::}{run()} is
|
||||
executed. It lives in the old thread.
|
||||
\li Most QThread methods are the thread's control interface and are meant to
|
||||
be called from the old thread. Do not move this interface to the newly
|
||||
created thread using \l{QObject::}{moveToThread()}; i.e., calling
|
||||
\l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad
|
||||
practice.
|
||||
\li \l{QThread::}{exec()} and the static methods
|
||||
\l{QThread::}{usleep()}, \l{QThread::}{msleep()},
|
||||
\l{QThread::}{sleep()} are meant to be called from the newly created
|
||||
thread.
|
||||
\li Additional members defined in the QThread subclass are
|
||||
accessible by both threads. The developer is responsible for
|
||||
coordinating access. A typical strategy is to set the members before
|
||||
\l{QThread::}{start()} is called. Once the worker thread is running,
|
||||
the main thread should not touch the additional members anymore. After
|
||||
the worker has terminated, the main thread can access the additional
|
||||
members again. This is a convenient strategy for passing parameters to a
|
||||
thread before it is started as well as for collecting the result once it
|
||||
has terminated.
|
||||
\endlist
|
||||
|
||||
\section2 Protecting the Integrity of Data
|
||||
|
||||
When writing a multithread application, extra care must be taken to avoid
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
\nextpage Synchronizing Threads
|
||||
|
||||
Qt offers many classes and functions for working with threads. Below are
|
||||
three different approaches that Qt programmers can use to implement
|
||||
four different approaches that Qt programmers can use to implement
|
||||
multithreaded applications.
|
||||
|
||||
|
||||
|
|
@ -163,19 +163,47 @@
|
|||
\section1 Qt Concurrent: Using a High-level API
|
||||
|
||||
The \l{Qt Concurrent} module provides high-level functions that deal with some
|
||||
common parallel computation patterns: map, filter, and reduce. Unlike QThread
|
||||
and QRunnable, these functions do not require the use of low-level threading
|
||||
primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically
|
||||
adjust the number of threads used according to the number of processor cores
|
||||
available, so applications written today will continue to scale when deployed
|
||||
later on a system with more cores.
|
||||
common parallel computation patterns: map, filter, and reduce. Unlike using
|
||||
QThread and QRunnable, these functions never require the use of \l{Synchronizing
|
||||
Threads#Low-Level Synchronization Primitives}{low-level threading primitives}
|
||||
such as mutexes or semaphores. Instead, they return a QFuture object which can
|
||||
be used to retrieve the functions' results when they are ready. QFuture can
|
||||
also be used to query computation progress and to pause/resume/cancel the
|
||||
computation. For convenience, QFutureWatcher enables interactions with
|
||||
\l{QFuture}s via signals and slots.
|
||||
|
||||
This module also provides the QtConcurrent::run() function, which can run
|
||||
any function in a thread managed by the global QThreadPool.
|
||||
\l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute
|
||||
computation across all available processor cores, so applications written today
|
||||
will continue to scale when deployed later on a system with more cores.
|
||||
|
||||
This module also provides the QtConcurrent::run() function, which can run any
|
||||
function in another thread. However, QtConcurrent::run() only supports a subset
|
||||
of features available to the map, filter and reduce functions. The QFuture
|
||||
can be used to retrieve the function's return value and to check if the thread
|
||||
is running. However, a call to QtConcurrent::run() uses one thread only, cannot
|
||||
be paused/resumed/canceled, and cannot be queried for progress.
|
||||
|
||||
See the \l{Qt Concurrent} module documentation for details on the individual functions.
|
||||
|
||||
|
||||
\section1 WorkerScript: Threading in QML
|
||||
|
||||
The WorkerScript QML type lets JavaScript code run in parallel with the GUI
|
||||
thread.
|
||||
|
||||
Each WorkerScript instance can have one \c{.js} script attached to it. When
|
||||
WorkerScript::sendMessage() is called, the script will run in a separate thread
|
||||
(and a separate \l{QQmlContext}{QML context}). When the script finishes
|
||||
running, it can send a reply back to the GUI thread which will invoke the
|
||||
WorkerScript::onMessage() signal handler.
|
||||
|
||||
Using a WorkerScript is similar to using a worker QObject that has been moved
|
||||
to another thread. Data is transferred between threads via signals.
|
||||
|
||||
See the WorkerScript documentation for details on how to implement the script,
|
||||
and for a list of data types that can be passed between threads.
|
||||
|
||||
|
||||
\section1 Choosing an Appropriate Approach
|
||||
|
||||
As demonstrated above, Qt provides different solutions for developing threaded
|
||||
|
|
@ -187,52 +215,62 @@
|
|||
|
||||
\table
|
||||
\header
|
||||
\li Feature/Characteristic
|
||||
\li Feature
|
||||
\li QThread
|
||||
\li QRunnable
|
||||
\li Qt Concurrent\sup{*}
|
||||
\li QRunnable and QThreadPool
|
||||
\li QtConcurrent::run()
|
||||
\li Qt Concurrent (Map, Filter, Reduce)
|
||||
\li WorkerScript
|
||||
\row
|
||||
\li Supports different thread priorities
|
||||
\li API
|
||||
\li C++
|
||||
\li C++
|
||||
\li C++
|
||||
\li C++
|
||||
\li QML
|
||||
\row
|
||||
\li Thread priority can be specified
|
||||
\li Yes
|
||||
\li Yes
|
||||
\li
|
||||
\li
|
||||
\li
|
||||
\row
|
||||
\li Supports an event loop
|
||||
\li Thread can run an event loop
|
||||
\li Yes
|
||||
\li
|
||||
\li
|
||||
\li
|
||||
\li
|
||||
\row
|
||||
\li Supports transferring data to the thread using signals
|
||||
\li Thread can receive data updates through signals
|
||||
\li Yes (received by a worker QObject)
|
||||
\li
|
||||
\li
|
||||
\li
|
||||
\li Yes (received by WorkerScript)
|
||||
\row
|
||||
\li Supports controlling the thread using signals
|
||||
\li Thread can be controlled using signals
|
||||
\li Yes (received by QThread)
|
||||
\li
|
||||
\li
|
||||
\li Yes (received by QFutureWatcher)
|
||||
\li
|
||||
\row
|
||||
\li Supports thread reuse
|
||||
\li Thread can be monitored through a QFuture
|
||||
\li
|
||||
\li
|
||||
\li Partially
|
||||
\li Yes
|
||||
\li Yes
|
||||
\li
|
||||
\row
|
||||
\li Task-oriented
|
||||
\li Built-in ability to pause/resume/cancel
|
||||
\li
|
||||
\li Yes
|
||||
\li Yes
|
||||
\row
|
||||
\li High level API
|
||||
\li
|
||||
\li
|
||||
\li Yes
|
||||
\row
|
||||
\li Supports pausing/resuming/canceling
|
||||
\li
|
||||
\li
|
||||
\li Yes
|
||||
\endtable
|
||||
\sup{\e{*Except QtConcurrent::run(), which is like QRunnable}}
|
||||
|
||||
|
||||
\section2 Example Use Cases
|
||||
|
|
@ -244,7 +282,7 @@
|
|||
\li Solution
|
||||
\row
|
||||
\li One call
|
||||
\li Run a linear function within another thread, optionally with progress
|
||||
\li Run a new linear function within another thread, optionally with progress
|
||||
updates during the run.
|
||||
\li Qt provides different solutions:
|
||||
\list
|
||||
|
|
@ -256,6 +294,13 @@
|
|||
\li Run the function using QtConcurrent::run(). Write to a \l{Synchronizing
|
||||
Threads}{thread-safe variable} to update progress.
|
||||
\endlist
|
||||
\row
|
||||
\li One call
|
||||
\li Run an existing function within another thread and get its return value.
|
||||
\li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit
|
||||
the \l{QFutureWatcher::}{finished()} signal when the function has
|
||||
returned, and call QFutureWatcher::result() to get the function's return
|
||||
value.
|
||||
\row
|
||||
\li One call
|
||||
\li Perform an operation on all items of a container, using all available
|
||||
|
|
@ -263,8 +308,17 @@
|
|||
\li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select
|
||||
container elements, and the \l{QtConcurrent::}{map()} function to apply
|
||||
an operation to each element. To fold the output into a single result,
|
||||
use \l{QtConcurrent::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()}
|
||||
instead.
|
||||
use \l{QtConcurrent::}{filteredReduced()} and
|
||||
\l{QtConcurrent::}{mappedReduced()} instead.
|
||||
\row
|
||||
\li One call/Permanent
|
||||
\li Perfrom a long computation in a pure QML application, and update the GUI
|
||||
when the results are ready.
|
||||
\li Place the computation code in a \c{.js} script and attach it to a
|
||||
WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the
|
||||
computation in a new thread. Let the script call WorkerScript::sendMessage()
|
||||
too, to pass the result back to the GUI thread. Handle the result in
|
||||
\l{WorkerScript::}{onMessage} and update the GUI there.
|
||||
\row
|
||||
\li Permanent
|
||||
\li Have an object living in another thread that can perform different
|
||||
|
|
|
|||
|
|
@ -165,6 +165,13 @@
|
|||
# /* Compatibility with older Clang versions */
|
||||
# define __has_extension __has_feature
|
||||
# endif
|
||||
# if defined(__APPLE__)
|
||||
/* Apple/clang specific features */
|
||||
# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
|
||||
# ifdef __OBJC__
|
||||
# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
/* Plain GCC */
|
||||
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
|
||||
|
|
@ -628,14 +635,6 @@
|
|||
# endif
|
||||
#endif // Q_CC_CLANG
|
||||
|
||||
#if defined(Q_CC_CLANG) && defined(__APPLE__)
|
||||
/* Apple/clang specific features */
|
||||
# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
|
||||
# ifdef __OBJC__
|
||||
# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
|
||||
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
|
||||
|
|
@ -704,15 +703,20 @@
|
|||
# if _MSC_VER >= 1400
|
||||
/* C++11 features supported in VC8 = VC2005: */
|
||||
# define Q_COMPILER_VARIADIC_MACROS
|
||||
|
||||
# ifndef __cplusplus_cli
|
||||
/* 2005 supports the override and final contextual keywords, in
|
||||
the same positions as the C++11 variants, but 'final' is
|
||||
called 'sealed' instead:
|
||||
http://msdn.microsoft.com/en-us/library/0w2w91tf%28v=vs.80%29.aspx
|
||||
The behavior is slightly different in C++/CLI, which requires the
|
||||
"virtual" keyword to be present too, so don't define for that.
|
||||
So don't define Q_COMPILER_EXPLICIT_OVERRIDES (since it's not
|
||||
the same as the C++11 version), but define the Q_DECL_* flags
|
||||
accordingly: */
|
||||
# define Q_DECL_OVERRIDE override
|
||||
# define Q_DECL_FINAL sealed
|
||||
# endif
|
||||
# endif
|
||||
# if _MSC_VER >= 1600
|
||||
/* C++11 features supported in VC10 = VC2010: */
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@
|
|||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
#include <private/qjni_p.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !QT_DEPRECATED_SINCE(5, 0)
|
||||
|
|
@ -2348,6 +2352,9 @@ typedef uint SeedStorageType;
|
|||
typedef QThreadStorage<SeedStorageType *> SeedStorage;
|
||||
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
|
||||
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
|
||||
Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
|
@ -2381,6 +2388,16 @@ void qsrand(uint seed)
|
|||
//global static object, fallback to srand(seed)
|
||||
srand(seed);
|
||||
}
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random",
|
||||
"(J)V",
|
||||
jlong(seed));
|
||||
if (!random.isValid()) {
|
||||
srand(seed);
|
||||
return;
|
||||
}
|
||||
|
||||
randomTLS->setLocalData(random);
|
||||
#else
|
||||
// On Windows srand() and rand() already use Thread-Local-Storage
|
||||
// to store the seed between calls
|
||||
|
|
@ -2422,6 +2439,25 @@ int qrand()
|
|||
//global static object, fallback to rand()
|
||||
return rand();
|
||||
}
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
AndroidRandomStorage *randomStorage = randomTLS();
|
||||
if (!randomStorage)
|
||||
return rand();
|
||||
|
||||
QJNIObjectPrivate random;
|
||||
if (!randomStorage->hasLocalData()) {
|
||||
random = QJNIObjectPrivate("java/util/Random",
|
||||
"(J)V",
|
||||
jlong(1));
|
||||
if (!random.isValid())
|
||||
return rand();
|
||||
|
||||
randomStorage->setLocalData(random);
|
||||
} else {
|
||||
random = randomStorage->localData();
|
||||
}
|
||||
|
||||
return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
|
||||
#else
|
||||
// On Windows srand() and rand() already use Thread-Local-Storage
|
||||
// to store the seed between calls
|
||||
|
|
|
|||
|
|
@ -1004,13 +1004,19 @@ template <bool B, typename T = void> struct QEnableIf;
|
|||
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
|
||||
}
|
||||
|
||||
#ifdef __OBJC__
|
||||
#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
|
||||
#else
|
||||
#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
|
||||
#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
|
||||
# ifdef __OBJC__
|
||||
# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
|
||||
# else
|
||||
# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Q_FORWARD_DECLARE_CF_TYPE
|
||||
# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
|
||||
#endif
|
||||
#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
|
||||
# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
|
||||
#endif
|
||||
#define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
|
||||
#define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
|
||||
|
||||
QT_END_NAMESPACE
|
||||
// Q_GLOBAL_STATIC
|
||||
|
|
|
|||
|
|
@ -57,11 +57,16 @@ enum GuardValues {
|
|||
};
|
||||
}
|
||||
|
||||
#if defined(QT_NO_THREAD) || defined(Q_CC_GNU)
|
||||
#if defined(QT_NO_THREAD) || (defined(Q_CC_GNU) && !defined(Q_OS_MAC))
|
||||
// some compilers support thread-safe statics
|
||||
// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4
|
||||
// support it. C++11 also requires this behavior.
|
||||
// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X.
|
||||
// Clang and Intel CC masquerade as GCC when compiling on Linux.
|
||||
//
|
||||
// Apple's libc++abi however uses a global lock for initializing local statics,
|
||||
// which will block other threads also trying to initialize a local static
|
||||
// until the constructor returns ...
|
||||
// We better avoid these kind of problems by using our own locked implementation.
|
||||
|
||||
#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
|
||||
Q_DECL_HIDDEN inline Type *innerFunction() \
|
||||
|
|
|
|||
|
|
@ -446,7 +446,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
|
|||
QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
|
||||
if (urlRef) {
|
||||
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
|
||||
#ifdef Q_OS_MACX
|
||||
return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret);
|
||||
#else
|
||||
return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@ static const char functionTokenC[] = "%{function}";
|
|||
static const char pidTokenC[] = "%{pid}";
|
||||
static const char appnameTokenC[] = "%{appname}";
|
||||
static const char threadidTokenC[] = "%{threadid}";
|
||||
static const char ifCategoryTokenC[] = "%{if-category}";
|
||||
static const char ifDebugTokenC[] = "%{if-debug}";
|
||||
static const char ifWarningTokenC[] = "%{if-warning}";
|
||||
static const char ifCriticalTokenC[] = "%{if-critical}";
|
||||
|
|
@ -556,7 +557,7 @@ static const char ifFatalTokenC[] = "%{if-fatal}";
|
|||
static const char endifTokenC[] = "%{endif}";
|
||||
static const char emptyTokenC[] = "";
|
||||
|
||||
static const char defaultPattern[] = "%{message}";
|
||||
static const char defaultPattern[] = "%{if-category}%{category}: %{endif}%{message}";
|
||||
|
||||
|
||||
struct QMessagePattern {
|
||||
|
|
@ -675,6 +676,7 @@ void QMessagePattern::setPattern(const QString &pattern)
|
|||
tokens[i] = LEVEL; \
|
||||
inIf = true; \
|
||||
}
|
||||
IF_TOKEN(ifCategoryTokenC)
|
||||
IF_TOKEN(ifDebugTokenC)
|
||||
IF_TOKEN(ifWarningTokenC)
|
||||
IF_TOKEN(ifCriticalTokenC)
|
||||
|
|
@ -837,6 +839,9 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
|
|||
message.append(QLatin1String("0x"));
|
||||
message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16));
|
||||
#endif
|
||||
} else if (token == ifCategoryTokenC) {
|
||||
if (!context.category || (strcmp(context.category, "default") == 0))
|
||||
skip = true;
|
||||
#define HANDLE_IF_TOKEN(LEVEL) \
|
||||
} else if (token == if##LEVEL##TokenC) { \
|
||||
skip = type != Qt##LEVEL##Msg;
|
||||
|
|
@ -927,7 +932,7 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
|
|||
#ifndef QT_BOOTSTRAPPED
|
||||
// qDebug, qWarning, ... macros do not check whether category is enabled
|
||||
if (!context.category || (strcmp(context.category, "default") == 0)) {
|
||||
if (QLoggingCategory *defaultCategory = &QLoggingCategory::defaultCategory()) {
|
||||
if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
|
||||
if (!defaultCategory->isEnabled(msgType))
|
||||
return;
|
||||
}
|
||||
|
|
@ -1108,6 +1113,7 @@ void qErrnoWarning(int code, const char *msg, ...)
|
|||
\table
|
||||
\header \li Placeholder \li Description
|
||||
\row \li \c %{appname} \li QCoreApplication::applicationName()
|
||||
\row \li \c %{category} \li Logging category
|
||||
\row \li \c %{file} \li Path to source file
|
||||
\row \li \c %{function} \li Function
|
||||
\row \li \c %{line} \li Line in source file
|
||||
|
|
|
|||
|
|
@ -907,7 +907,7 @@ public:
|
|||
Key_BrightnessAdjust = 0x010000c2,
|
||||
Key_Finance = 0x010000c3,
|
||||
Key_Community = 0x010000c4,
|
||||
Key_AudioRewind = 0x010000c5,
|
||||
Key_AudioRewind = 0x010000c5, // Media rewind
|
||||
Key_BackForward = 0x010000c6,
|
||||
Key_ApplicationLeft = 0x010000c7,
|
||||
Key_ApplicationRight = 0x010000c8,
|
||||
|
|
@ -919,7 +919,7 @@ public:
|
|||
Key_Close = 0x010000ce,
|
||||
Key_Copy = 0x010000cf,
|
||||
Key_Cut = 0x010000d0,
|
||||
Key_Display = 0x010000d1,
|
||||
Key_Display = 0x010000d1, // Output switch key
|
||||
Key_DOS = 0x010000d2,
|
||||
Key_Documents = 0x010000d3,
|
||||
Key_Excel = 0x010000d4,
|
||||
|
|
@ -968,9 +968,9 @@ public:
|
|||
Key_Bluetooth = 0x010000ff,
|
||||
Key_WLAN = 0x01000100,
|
||||
Key_UWB = 0x01000101,
|
||||
Key_AudioForward = 0x01000102,
|
||||
Key_AudioRepeat = 0x01000103,
|
||||
Key_AudioRandomPlay = 0x01000104,
|
||||
Key_AudioForward = 0x01000102, // Media fast-forward
|
||||
Key_AudioRepeat = 0x01000103, // Toggle repeat mode
|
||||
Key_AudioRandomPlay = 0x01000104, // Toggle shuffle mode
|
||||
Key_Subtitle = 0x01000105,
|
||||
Key_AudioCycleTrack = 0x01000106,
|
||||
Key_Time = 0x01000107,
|
||||
|
|
@ -1557,6 +1557,18 @@ public:
|
|||
IgnoredGesturesPropagateToParent = 0x04
|
||||
};
|
||||
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
|
||||
|
||||
enum NativeGestureType
|
||||
{
|
||||
BeginNativeGesture,
|
||||
EndNativeGesture,
|
||||
PanNativeGesture,
|
||||
ZoomNativeGesture,
|
||||
SmartZoomNativeGesture,
|
||||
RotateNativeGesture,
|
||||
SwipeNativeGesture
|
||||
};
|
||||
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
enum NavigationMode
|
||||
|
|
|
|||
|
|
@ -1735,6 +1735,8 @@
|
|||
\value LeftEdge The left edge of the rectangle.
|
||||
\value RightEdge The right edge of the rectangle.
|
||||
\value BottomEdge The bottom edge of the rectangle.
|
||||
|
||||
\since 5.1
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -675,6 +675,8 @@ bool QFileInfo::exists() const
|
|||
}
|
||||
|
||||
/*!
|
||||
\since 5.2
|
||||
|
||||
Returns \c true if the \a file exists; otherwise returns \c false.
|
||||
|
||||
\note If \a file is a symlink that points to a non-existing
|
||||
|
|
@ -691,7 +693,8 @@ bool QFileInfo::exists(const QString &file)
|
|||
QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data);
|
||||
// Expensive fallback to non-QFileSystemEngine implementation
|
||||
if (engine)
|
||||
return QFileInfo(file).exists();
|
||||
return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists();
|
||||
|
||||
QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
|
||||
return data.exists();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,20 @@ public:
|
|||
metaData = QFileSystemMetaData();
|
||||
}
|
||||
|
||||
inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine)
|
||||
: fileEntry(file),
|
||||
metaData(data),
|
||||
fileEngine(engine),
|
||||
cachedFlags(0),
|
||||
#ifndef QT_NO_FSFILEENGINE
|
||||
isDefaultConstructed(false),
|
||||
#else
|
||||
isDefaultConstructed(!fileEngine),
|
||||
#endif
|
||||
cache_enabled(true), fileFlags(0), fileSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void clearFlags() const {
|
||||
fileFlags = 0;
|
||||
cachedFlags = 0;
|
||||
|
|
|
|||
|
|
@ -1038,8 +1038,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
|
|||
return data.hasFlags(what);
|
||||
}
|
||||
|
||||
static inline bool mkDir(const QString &path)
|
||||
static inline bool mkDir(const QString &path, DWORD *lastError = 0)
|
||||
{
|
||||
if (lastError)
|
||||
*lastError = 0;
|
||||
#if defined(Q_OS_WINCE)
|
||||
// Unfortunately CreateDirectory returns true for paths longer than
|
||||
// 256, but does not create a directory. It starts to fail, when
|
||||
|
|
@ -1059,7 +1061,11 @@ static inline bool mkDir(const QString &path)
|
|||
if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256)
|
||||
return false;
|
||||
#endif
|
||||
return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0);
|
||||
const QString longPath = QFSFileEnginePrivate::longFileName(path);
|
||||
const bool result = ::CreateDirectory((wchar_t*)longPath.utf16(), 0);
|
||||
if (lastError) // Capture lastError before any QString is freed since custom allocators might change it.
|
||||
*lastError = GetLastError();
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool rmDir(const QString &path)
|
||||
|
|
@ -1131,9 +1137,9 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
|
|||
slash = dirName.length();
|
||||
}
|
||||
if (slash) {
|
||||
DWORD lastError;
|
||||
QString chunk = dirName.left(slash);
|
||||
if (!mkDir(chunk)) {
|
||||
const DWORD lastError = GetLastError();
|
||||
if (!mkDir(chunk, &lastError)) {
|
||||
if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) {
|
||||
bool existed = false;
|
||||
if (isDirPath(chunk, &existed) && existed)
|
||||
|
|
|
|||
|
|
@ -99,8 +99,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
|
|||
#define CHECK_WRITABLE(function, returnType) \
|
||||
do { \
|
||||
if ((d->openMode & WriteOnly) == 0) { \
|
||||
if (d->openMode == NotOpen) \
|
||||
if (d->openMode == NotOpen) { \
|
||||
qWarning("QIODevice::"#function": device not open"); \
|
||||
return returnType; \
|
||||
} \
|
||||
qWarning("QIODevice::"#function": ReadOnly device"); \
|
||||
return returnType; \
|
||||
} \
|
||||
|
|
@ -109,8 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
|
|||
#define CHECK_READABLE(function, returnType) \
|
||||
do { \
|
||||
if ((d->openMode & ReadOnly) == 0) { \
|
||||
if (d->openMode == NotOpen) \
|
||||
if (d->openMode == NotOpen) { \
|
||||
qWarning("QIODevice::"#function": device not open"); \
|
||||
return returnType; \
|
||||
} \
|
||||
qWarning("QIODevice::"#function": WriteOnly device"); \
|
||||
return returnType; \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -140,6 +140,13 @@ static bool setNativeLocks(int fd)
|
|||
|
||||
QLockFile::LockError QLockFilePrivate::tryLock_sys()
|
||||
{
|
||||
// Assemble data, to write in a single call to write
|
||||
// (otherwise we'd have to check every write call)
|
||||
// Use operator% from the fast builder to avoid multiple memory allocations.
|
||||
QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'
|
||||
% qAppName().toUtf8() % '\n'
|
||||
% localHostName().toUtf8() % '\n';
|
||||
|
||||
const QByteArray lockFileName = QFile::encodeName(fileName);
|
||||
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644);
|
||||
if (fd < 0) {
|
||||
|
|
@ -160,16 +167,6 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
|
|||
// We hold the lock, continue.
|
||||
fileHandle = fd;
|
||||
|
||||
// Assemble data, to write in a single call to write
|
||||
// (otherwise we'd have to check every write call)
|
||||
QByteArray fileData;
|
||||
fileData += QByteArray::number(QCoreApplication::applicationPid());
|
||||
fileData += '\n';
|
||||
fileData += qAppName().toUtf8();
|
||||
fileData += '\n';
|
||||
fileData += localHostName().toUtf8();
|
||||
fileData += '\n';
|
||||
|
||||
QLockFile::LockError error = QLockFile::NoError;
|
||||
if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size())
|
||||
error = QLockFile::UnknownError; // partition full
|
||||
|
|
|
|||
|
|
@ -71,30 +71,36 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
|
|||
|
||||
\section1 Checking category configuration
|
||||
|
||||
QLoggingCategory provides a generic \l isEnabled() and message
|
||||
type dependent \l isDebugEnabled(), \l isWarningEnabled(),
|
||||
\l isCriticalEnabled() and \l isTraceEnabled()
|
||||
methods for checking whether the current category is enabled.
|
||||
QLoggingCategory provides \l isDebugEnabled(), \l isWarningEnabled(),
|
||||
\l isCriticalEnabled(), \l isTraceEnabled(), as well as \l isEnabled()
|
||||
to check whether messages for the given message type should be logged.
|
||||
|
||||
\note The qCDebug(), qCWarning(), qCCritical(), qCTrace() and
|
||||
qCTraceGuard() macros prevent arguments from being evaluated if the
|
||||
respective message types are not enabled for the category, so explicit
|
||||
checking is not needed:
|
||||
|
||||
\snippet qloggingcategory/main.cpp 3
|
||||
\snippet qloggingcategory/main.cpp 4
|
||||
|
||||
\section1 Default configuration
|
||||
\section1 Default category configuration
|
||||
|
||||
In the default configuration \l isWarningEnabled() and \l isCriticalEnabled()
|
||||
will return \c true. By default, \l isDebugEnabled() will return \c true only
|
||||
will return \c true. \l isDebugEnabled() will return \c true only
|
||||
for the \c "default" category.
|
||||
|
||||
\section1 Changing configuration
|
||||
\section1 Changing the configuration of a category
|
||||
|
||||
The default configuration can be changed by calling \l setEnabled(). However,
|
||||
this only affects the current category object, not e.g. another object for the
|
||||
same category name. Use either \l setFilterRules() or \l installFilter() to
|
||||
configure categories globally.
|
||||
Use either \l setFilterRules() or \l installFilter() to
|
||||
configure categories, for example
|
||||
|
||||
\snippet qloggingcategory/main.cpp 2
|
||||
|
||||
\section1 Printing the category
|
||||
|
||||
Use the \c %{category} place holder to print the category in the default
|
||||
message handler:
|
||||
|
||||
\snippet qloggingcategory/main.cpp 3
|
||||
*/
|
||||
|
||||
typedef QVector<QTracer *> Tracers;
|
||||
|
|
@ -117,7 +123,10 @@ QLoggingCategory::QLoggingCategory(const char *category)
|
|||
enabledDebug(false),
|
||||
enabledWarning(true),
|
||||
enabledCritical(true),
|
||||
enabledTrace(false)
|
||||
enabledTrace(false),
|
||||
placeholder1(false),
|
||||
placeholder2(false),
|
||||
placeholder3(false)
|
||||
{
|
||||
bool isDefaultCategory
|
||||
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
|
||||
|
|
@ -215,14 +224,12 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
|
|||
/*!
|
||||
Changes the message type \a type for the category to \a enable.
|
||||
|
||||
Changes only affect the current QLoggingCategory object, and won't
|
||||
change e.g. the settings of another objects for the same category name.
|
||||
\note Changes only affect the current QLoggingCategory object, and won't
|
||||
change the settings of other objects for the same category name.
|
||||
Use either \l setFilterRules() or \l installFilter() to change the
|
||||
configuration globally.
|
||||
|
||||
\note \c QtFatalMsg cannot be changed. It will always return \c true.
|
||||
|
||||
Example:
|
||||
|
||||
\snippet qtracer/ftracer.cpp 5
|
||||
*/
|
||||
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
|
||||
{
|
||||
|
|
@ -244,12 +251,19 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
|
|||
*/
|
||||
|
||||
/*!
|
||||
Returns the category \c "default" that is used e.g. by qDebug(), qWarning(),
|
||||
qCritical(), qFatal().
|
||||
Returns a pointer to the global category \c "default" that
|
||||
is used e.g. by qDebug(), qWarning(), qCritical(), qFatal().
|
||||
|
||||
\note The returned pointer may be null during destruction of
|
||||
static objects.
|
||||
|
||||
\note Ownership of the category is not transferred, do not
|
||||
\c delete the returned pointer.
|
||||
|
||||
*/
|
||||
QLoggingCategory &QLoggingCategory::defaultCategory()
|
||||
QLoggingCategory *QLoggingCategory::defaultCategory()
|
||||
{
|
||||
return *qtDefaultCategory();
|
||||
return qtDefaultCategory();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -272,6 +286,12 @@ QLoggingCategory &QLoggingCategory::defaultCategory()
|
|||
filter is free to change the respective category configuration with
|
||||
\l setEnabled().
|
||||
|
||||
The filter might be called concurrently from different threads, and
|
||||
therefore has to be reentrant.
|
||||
|
||||
Example:
|
||||
\snippet qloggingcategory/main.cpp 21
|
||||
|
||||
An alternative way of configuring the default filter is via
|
||||
\l setFilterRules().
|
||||
*/
|
||||
|
|
@ -281,7 +301,6 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
|
|||
return QLoggingRegistry::instance()->installFilter(filter);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Configures which categories and message types should be enabled through a
|
||||
a set of \a rules.
|
||||
|
|
@ -296,8 +315,13 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
|
|||
wildcard symbol at the start and/or the end. The optional \c <type> must
|
||||
be either \c debug, \c warning, \c critical, or \c trace.
|
||||
|
||||
The rules might be ignored if a custom category filter is installed with
|
||||
\l installFilter().
|
||||
Example:
|
||||
|
||||
\snippet qloggingcategory/main.cpp 2
|
||||
|
||||
\note The rules might be ignored if a custom category filter is installed
|
||||
with \l installFilter().
|
||||
|
||||
*/
|
||||
void QLoggingCategory::setFilterRules(const QString &rules)
|
||||
{
|
||||
|
|
@ -380,7 +404,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||
|
||||
The macro expands to code that checks whether
|
||||
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
|
||||
If so, the stream arguments are processed and sent to the tracers
|
||||
If so, the stream arguments are processed and sent to the \l QTracer objects
|
||||
registered with the category.
|
||||
|
||||
\note Arguments are not processed if trace output for the category is not
|
||||
|
|
@ -390,7 +414,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||
|
||||
\snippet qtracer/ftracer.cpp 6
|
||||
|
||||
\sa qCTraceGuard()
|
||||
\sa qCTraceGuard() QTraceGuard
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
@ -402,11 +426,12 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||
storage. The guard constructor checks whether
|
||||
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
|
||||
If so, the stream arguments are processed and the \c{start()}
|
||||
functions of the tracers registered with the \a category are called.
|
||||
functions of the \l QTracer objects registered with the \a category are
|
||||
called.
|
||||
|
||||
The guard destructor also checks whether the category is enabled for
|
||||
tracing and if so, the \c{end()}
|
||||
functions of the tracers registered with the \a category are called.
|
||||
functions of the \l QTracer objects registered with the \a category are called.
|
||||
|
||||
\note Arguments are always processed, even if trace output for the
|
||||
category is disabled. They will, however, in that case not be passed
|
||||
|
|
@ -416,7 +441,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||
|
||||
\snippet qtracer/ftracer.cpp 4
|
||||
|
||||
\sa qCTrace()
|
||||
\sa qCTrace() QTracer
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public:
|
|||
// allows usage of both factory method and variable in qCX macros
|
||||
QLoggingCategory &operator()() { return *this; }
|
||||
|
||||
static QLoggingCategory &defaultCategory();
|
||||
static QLoggingCategory *defaultCategory();
|
||||
|
||||
typedef void (*CategoryFilter)(QLoggingCategory*);
|
||||
static CategoryFilter installFilter(CategoryFilter);
|
||||
|
|
@ -92,6 +92,10 @@ private:
|
|||
bool enabledWarning;
|
||||
bool enabledCritical;
|
||||
bool enabledTrace;
|
||||
// reserve space for future use
|
||||
bool placeholder1;
|
||||
bool placeholder2;
|
||||
bool placeholder3;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QTracer
|
||||
|
|
|
|||
|
|
@ -1840,12 +1840,21 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
|
|||
input. It must also start with an ASCII letter.
|
||||
|
||||
The scheme describes the type (or protocol) of the URL. It's
|
||||
represented by one or more ASCII characters at the start the URL,
|
||||
and is followed by a ':'. The following example shows a URL where
|
||||
the scheme is "ftp":
|
||||
represented by one or more ASCII characters at the start the URL.
|
||||
|
||||
A scheme is strictly \l {http://www.ietf.org/rfc/rfc3986.txt} {RFC 3986}-compliant:
|
||||
\tt {scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )}
|
||||
|
||||
The following example shows a URL where the scheme is "ftp":
|
||||
|
||||
\image qurl-authority2.png
|
||||
|
||||
To set the scheme, the following call is used:
|
||||
\code
|
||||
QUrl url;
|
||||
url.setScheme("ftp");
|
||||
\endcode
|
||||
|
||||
The scheme can also be empty, in which case the URL is interpreted
|
||||
as relative.
|
||||
|
||||
|
|
@ -3327,7 +3336,7 @@ QString QUrl::fromPercentEncoding(const QByteArray &input)
|
|||
them to \a include.
|
||||
|
||||
Unreserved is defined as:
|
||||
ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
\tt {ALPHA / DIGIT / "-" / "." / "_" / "~"}
|
||||
|
||||
\snippet code/src_corelib_io_qurl.cpp 6
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *b
|
|||
// we've decoded something; safety-check it
|
||||
if (uc < min_uc)
|
||||
return false;
|
||||
if (QChar::isSurrogate(uc) || QChar::isNonCharacter(uc) || uc > QChar::LastValidCodePoint)
|
||||
if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
|
||||
return false;
|
||||
|
||||
if (!QChar::requiresSurrogates(uc)) {
|
||||
|
|
@ -410,10 +410,9 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl:
|
|||
const ushort *input = begin;
|
||||
ushort *output = 0;
|
||||
|
||||
EncodingAction action = EncodeCharacter;
|
||||
for ( ; input != end; ++input) {
|
||||
ushort c;
|
||||
EncodingAction action;
|
||||
|
||||
// try a run where no change is necessary
|
||||
for ( ; input != end; ++input) {
|
||||
c = *input;
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,7 @@ void QJsonArray::compact()
|
|||
}
|
||||
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
QDebug operator<<(QDebug dbg, const QJsonArray &a)
|
||||
{
|
||||
if (!a.a) {
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ private:
|
|||
QJsonPrivate::Array *a;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -303,10 +303,12 @@ QVariant QJsonDocument::toVariant() const
|
|||
|
||||
\sa fromJson()
|
||||
*/
|
||||
#ifndef QT_JSON_READONLY
|
||||
QByteArray QJsonDocument::toJson() const
|
||||
{
|
||||
return toJson(Indented);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\enum QJsonDocument::JsonFormat
|
||||
|
|
@ -338,6 +340,7 @@ QByteArray QJsonDocument::toJson() const
|
|||
|
||||
\sa fromJson(), JsonFormat
|
||||
*/
|
||||
#ifndef QT_JSON_READONLY
|
||||
QByteArray QJsonDocument::toJson(JsonFormat format) const
|
||||
{
|
||||
if (!d)
|
||||
|
|
@ -352,6 +355,7 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const
|
|||
|
||||
return json;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Parses a UTF-8 encoded JSON document and creates a QJsonDocument
|
||||
|
|
@ -562,7 +566,7 @@ bool QJsonDocument::isNull() const
|
|||
return (d == 0);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
QDebug operator<<(QDebug dbg, const QJsonDocument &o)
|
||||
{
|
||||
if (!o.d) {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public:
|
|||
|
||||
#ifdef Q_QDOC
|
||||
QByteArray toJson(JsonFormat format = Indented) const;
|
||||
#else
|
||||
#elif !defined(QT_JSON_READONLY)
|
||||
QByteArray toJson() const; //### Merge in Qt6
|
||||
QByteArray toJson(JsonFormat format) const;
|
||||
#endif
|
||||
|
|
@ -148,7 +148,7 @@ private:
|
|||
QJsonPrivate::Data *d;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1036,7 +1036,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
|
|||
insert(e->key(), val);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
QDebug operator<<(QDebug dbg, const QJsonObject &o)
|
||||
{
|
||||
if (!o.o) {
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ private:
|
|||
QJsonPrivate::Object *o;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -853,7 +853,7 @@ static inline bool scanUtf8Char(const char *&json, const char *end, uint *result
|
|||
uc = (uc << 6) | (ch & 0x3f);
|
||||
}
|
||||
|
||||
if (uc < min_uc || QChar::isNonCharacter(uc) ||
|
||||
if (uc < min_uc ||
|
||||
QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue