diff options
Diffstat (limited to 'qmake')
74 files changed, 2168 insertions, 2275 deletions
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 10c72bf28f..873d65a97c 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -9,7 +9,7 @@ OBJS=project.o option.o property.o main.o ioutils.o proitems.o \ mingw_make.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ msvc_vcproj.o msvc_vcxproj.o msvc_nmake.o msvc_objectmodel.o msbuild_objectmodel.o \ - gbuild.o cesdkhandler.o + cesdkhandler.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtextstream.o qiodevice.o \ @@ -33,7 +33,7 @@ DEPEND_SRC = \ $(QMKGENSRC)/makefiledeps.cpp $(QMKGENSRC)/metamakefile.cpp \ $(QMKGENSRC)/projectgenerator.cpp $(QMKGENSRC)/makefile.cpp \ $(QMKGENSRC)/unix/unixmake.cpp $(QMKGENSRC)/unix/unixmake2.cpp \ - $(QMKGENSRC)/mac/pbuilder_pbx.cpp $(QMKGENSRC)/integrity/gbuild.cpp \ + $(QMKGENSRC)/mac/pbuilder_pbx.cpp \ $(QMKGENSRC)/win32/winmakefile.cpp \ $(QMKGENSRC)/win32/mingw_make.cpp $(QMKGENSRC)/win32/msvc_nmake.cpp \ $(QMKGENSRC)/win32/cesdkhandler.cpp $(QMKGENSRC)/mac/xmloutput.cpp \ @@ -74,6 +74,7 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp \ $(SOURCE_PATH)/src/corelib/tools/qhash.cpp $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp \ + $(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm \ $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp \ $(SOURCE_PATH)/src/corelib/io/qsettings.cpp $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp \ $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \ @@ -208,9 +209,6 @@ cesdkhandler.o: $(QMKSRC)/generators/win32/cesdkhandler.cpp pbuilder_pbx.o: $(QMKSRC)/generators/mac/pbuilder_pbx.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -gbuild.o: $(QMKSRC)/generators/integrity/gbuild.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $< - projectgenerator.o: $(QMKSRC)/generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< @@ -269,6 +267,9 @@ qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp qcore_mac.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp +qcore_mac_objc.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm + qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 4a1347c954..f84c30d4af 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -1,5 +1,3 @@ -!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2013" || "$(QMAKESPEC)" == "win32-icc" - !if "$(SOURCE_PATH)" == "" SOURCE_PATH = .. !endif @@ -10,25 +8,25 @@ BUILD_PATH = .. QMKSRC = $(SOURCE_PATH)\qmake # -# specific stuff for NMake and ICC +# per-compiler options # !if "$(QMAKESPEC)" == "win32-icc" -CXX = icl -LINKER = link -CFLAGS = /Zc:forScope +CXX = icl +LINKER = link +CFLAGS_EXTRA = /Zc:forScope !else -CXX = cl -LINKER = link -!endif - -# -# specific stuff for VS2005 -# -!if "$(QMAKESPEC)" == "win32-msvc2005" +CXX = cl +LINKER = link +! if "$(QMAKESPEC)" == "win32-msvc2005" CFLAGS_EXTRA = /Zc:wchar_t- -!elseif "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2013" -CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS $(CFLAGS_CRT) -!endif +! elseif "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2013" +CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS $(CFLAGS_CRT) +! elseif "$(QMAKESPEC)" == "win32-msvc2015" +CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 $(CFLAGS_CRT) +! else +! error Unsupported compiler for this Makefile +! endif +!endif # !win32-icc CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ -W3 -nologo -O1 \ @@ -52,10 +50,6 @@ LIBS = ole32.lib advapi32.lib shell32.lib LINKQMAKE = $(LINKER) $(LFLAGS) -OUT:qmake.exe $(OBJS) $(QTOBJS) $(LIBS) ADDCLEAN = qmake.pdb qmake.ilk -!ELSE -!ERROR Unsupported compiler for this Makefile -!ENDIF - #qmake code OBJS = project.obj main.obj ioutils.obj proitems.obj qmakevfs.obj \ qmakeglobals.obj qmakeparser.obj qmakeevaluator.obj qmakebuiltins.obj \ @@ -64,7 +58,7 @@ OBJS = project.obj main.obj ioutils.obj proitems.obj qmakevfs.obj \ makefiledeps.obj metamakefile.obj xmloutput.obj \ msvc_nmake.obj msvc_vcproj.obj msvc_vcxproj.obj \ msvc_objectmodel.obj msbuild_objectmodel.obj registry.obj \ - gbuild.obj cesdkhandler.obj + cesdkhandler.obj #qt code QTOBJS= \ diff --git a/qmake/cachekeys.h b/qmake/cachekeys.h index 3d8e795ec3..1c977444e4 100644 --- a/qmake/cachekeys.h +++ b/qmake/cachekeys.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.cpp b/qmake/doc/snippets/code/doc_src_qmake-manual.cpp index bd63e600cd..a320c903b6 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.cpp +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro index 1bd89d2f04..857a311e91 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/delegate.h b/qmake/doc/snippets/qmake/delegate.h index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/delegate.h +++ b/qmake/doc/snippets/qmake/delegate.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/main.cpp b/qmake/doc/snippets/qmake/main.cpp index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/main.cpp +++ b/qmake/doc/snippets/qmake/main.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/model.cpp b/qmake/doc/snippets/qmake/model.cpp index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/model.cpp +++ b/qmake/doc/snippets/qmake/model.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/model.h b/qmake/doc/snippets/qmake/model.h index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/model.h +++ b/qmake/doc/snippets/qmake/model.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/paintwidget_mac.cpp b/qmake/doc/snippets/qmake/paintwidget_mac.cpp index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/paintwidget_mac.cpp +++ b/qmake/doc/snippets/qmake/paintwidget_mac.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/paintwidget_unix.cpp b/qmake/doc/snippets/qmake/paintwidget_unix.cpp index c39fc2cbf6..7e6796e111 100644 --- a/qmake/doc/snippets/qmake/paintwidget_unix.cpp +++ b/qmake/doc/snippets/qmake/paintwidget_unix.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/paintwidget_win.cpp b/qmake/doc/snippets/qmake/paintwidget_win.cpp index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/paintwidget_win.cpp +++ b/qmake/doc/snippets/qmake/paintwidget_win.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/precompile-stable.h b/qmake/doc/snippets/qmake/precompile-stable.h index eef8cef728..c1e646eb32 100644 --- a/qmake/doc/snippets/qmake/precompile-stable.h +++ b/qmake/doc/snippets/qmake/precompile-stable.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/snippets/qmake/view.h b/qmake/doc/snippets/qmake/view.h index 92c7eb6a48..d42d1b6a41 100644 --- a/qmake/doc/snippets/qmake/view.h +++ b/qmake/doc/snippets/qmake/view.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -17,8 +17,8 @@ ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index e7d125a3a8..2def71c723 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -10,15 +10,15 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free ** Documentation License version 1.3 as published by the Free Software ** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure +** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements ** will be met: http://www.gnu.org/copyleft/fdl.html. ** $QT_END_LICENSE$ @@ -2556,18 +2556,64 @@ \li The unique ID of the app. Defaults to reusing the existing generated manifest's UUID, or generates a new UUID if none is present. \row + \li logo_30x30 + \li Logo image file of size 30x30 pixels. This is not supported on Windows Phone. + \row + \li logo_41x41 + \li Logo image file of size 41x41 pixels. This is only supported on Windows Phone. + \row + \li logo_70x70 + \li Logo image file of size 70x70 pixels. This is not supported on Windows Phone. + \row + \li logo_71x71 + \li Logo image file of size 71x71 pixels. This is only supported on Windows Phone. + \row + \li logo_150x150 + \li Logo image file of size 150x150 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_310x150 + \li Logo image file of size 310x150 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_310x310 + \li Logo image file of size 310x310 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_620x300 + \li Splash screen image file of size 620x300 pixels. This is not supported on + Windows Phone. + \row + \li logo_480x800 + \li Splash sceen image file of size 480x800 pixels. This is only supported on + Windows Phone. + \row \li logo_large - \li Large logo image file. Default provided by the mkspec. + \li Large logo image file. This has to be 150x150 pixels. Supported on all + Windows Store App platforms. Default provided by the mkspec. \row \li logo_medium - \li Medium logo image file. Default provided by the mkspec. + \li Medium logo image file. For Windows Phone the image must have a pixel size + of 71x71, for other Windows Store App platforms 70x70. Default provided by + the mkspec. \row \li logo_small - \li Small logo image file. Default provided by the mkspec. + \li Small logo image file. For Windows Phone the image must have a pixel size + of 44x44, for other Windows Store App platforms 30x30. Default provided by + the mkspec. + \row + \li logo_splash + \li Splash screen image file. For Windows Phone the image must have a pixel size + of 480x800, for other Windows Store App platforms 620x300. Default provided + by the mkspec. \row \li logo_store \li Logo image file for Windows Store. Default provided by the mkspec. \row + \li logo_wide + \li Wide logo image file. This has to be 310x150 pixels. Supported on all + Windows Store App platforms. Default provided by the mkspec. + \row \li name \li The name of the package as displayed to the user. Defaults to TARGET. \row @@ -2583,9 +2629,6 @@ \li publisher_id \li The publisher's distinguished name (default: \c{CN=MyCN}). \row - \li splash_screen - \li Splash screen image file. Default provided by the mkspec. - \row \li target \li The name of the target (.exe). Defaults to TARGET. \row @@ -2612,6 +2655,10 @@ WINRT_MANIFEST = someManifest.xml.in \endcode + \note The required image sizes of \e logo_small, \e logo_medium, and \e logo_large + depend on the target platform. The general descriptions are overwritten if a + description that specifies the size is provided. + \target YACCSOURCES \section1 YACCSOURCES diff --git a/qmake/generators/integrity/gbuild.cpp b/qmake/generators/integrity/gbuild.cpp deleted file mode 100644 index 980c45bfb1..0000000000 --- a/qmake/generators/integrity/gbuild.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gbuild.h" -#include "option.h" -#include "meta.h" -#include <qdir.h> -#include <qregexp.h> -#include <qdebug.h> -#include <stdlib.h> -#include <time.h> -#ifdef Q_OS_UNIX -# include <sys/types.h> -# include <sys/stat.h> -#endif - -QT_BEGIN_NAMESPACE - -unsigned int dllbase = 0x01000000; -#define DLLOFFSET 0x600000 - -GBuildMakefileGenerator::GBuildMakefileGenerator() : MakefileGenerator() -{ - nativebins << "moc" << "rcc" << "uic" << "bootstrap"; -} - -bool -GBuildMakefileGenerator::write() -{ - QStringList tmp; - QString filename(Option::output.fileName()); - QString pathtoremove(qmake_getpwd()); - QString relpath(pathtoremove); - QString strtarget(project->first("TARGET").toQString()); - bool isnativebin = nativebins.contains(strtarget); - relpath.replace(Option::output_dir, ""); - - /* correct output for non-prl, non-recursive case */ - QString outname(qmake_getpwd()); - outname += QDir::separator(); - outname += fileInfo(Option::output.fileName()).baseName(); - outname += projectSuffix(); - Option::output.close(); - Option::output.setFileName(outname); - MakefileGenerator::openOutput(Option::output, QString()); - - if (strtarget != fileInfo(project->projectFile()).baseName()) { - QString gpjname(strtarget); - QString outputName(qmake_getpwd()); - outputName += QDir::separator(); - outputName += fileInfo(project->projectFile()).baseName(); - outputName += projectSuffix(); - QFile f(outputName); - f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - QTextStream t(&f); - t << "#!gbuild\n"; - t << "[Project]\n"; - t << gpjname << projectSuffix() << "\n"; - if ((project->first("TEMPLATE") == "lib") - && project->isActiveConfig("shared")) - t << gpjname << "_shared" << projectSuffix() << "\n"; - t.flush(); - gpjname += projectSuffix(); - Option::output.close(); - Option::output.setFileName(gpjname); - MakefileGenerator::openOutput(Option::output, QString()); - } - - if ((project->first("TEMPLATE") == "app") - && (!isnativebin)) { - QTextStream t(&Option::output); - QString intname(strtarget); - intname += ".int"; - /* this is for bulding an INTEGRITY application. - * generate the .int integrate file and the .gpj INTEGRITY Application - * project file, then go on with regular files */ - t << "#!gbuild\n"; - t << "[INTEGRITY Application]\n"; - t << "\t:binDirRelative=.\n"; - t << "\t-o " << strtarget << "\n"; - t << intname << "\n"; - t << strtarget << "_app" << projectSuffix() << "\n"; - t.flush(); - - /* generate integrate file */ - QFile f(intname); - f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - QTextStream ti(&f); - ti << "# This is a file automatically generated by qmake\n"; - ti << "# Modifications will be lost next time you run qmake\n"; - ti << "Kernel\n"; - ti << "\tFilename\tDynamicDownload\n"; - ti << "EndKernel\n\n"; - ti << "AddressSpace\n"; - ti << "\tName\t" << strtarget << "\n"; - ti << "\tFilename\t" << strtarget << "_app\n"; - ti << "\tMemoryPoolSize\t0x100000\n"; - ti << "\tLanguage\tC++\n"; - /* FIXME : heap size is huge to be big enough for every example - * it should probably be tailored for each example, btu there is no - * good way to guess that */ - ti << "\tHeapSize\t0x00D00000\n"; - ti << "\tTask\tInitial\n"; - ti << "\t\tStackSize\t0x30000\n"; - ti << "\tEndTask\n"; - ti << "EndAddressSpace\n"; - ti.flush(); - - /* change current project file to <projectname>_app.gpj and continue - * generation */ - filename.insert(filename.lastIndexOf("."), "_app"); - Option::output.close(); - Option::output.setFileName(filename); - MakefileGenerator::openOutput(Option::output, QString()); - } else if ((project->first("TEMPLATE") == "lib") - && project->isActiveConfig("shared")) { - QString gpjname(strtarget); - gpjname += "_shared"; - gpjname += projectSuffix(); - QFile f(gpjname); - f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - QTextStream t(&f); - t << "#!gbuild\n" - "[Program]\n" - "\t-A libINTEGRITY.so\n" - "\t-A libc.so\n" - "\t-A libscxx.so\n" - "\t-A libQtCore.so\n" - "\t-e __ghsbegin_text\n" - "\t-startfile=-\n" - "\t:syslibraries=-\n" - "\t-Onolink\n"; - t << "\t-o lib" << strtarget << ".so\n"; - t << "\t-l" << strtarget << "\n"; - t << "\t-extractall=-l" << strtarget << "\n"; - t << "\t:outputDir=work/" << filename.section(QDir::separator(), 0, -1).remove(".gpj") << "\n"; - t << strtarget << "_shared.ld\n"; - t << "$(__OS_DIR)/intlib/sharedobjbssinit.c\n"; - t.flush(); - - QFile fl(strtarget + "_shared.ld"); - fl.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - QTextStream tl(&fl); - tl << "CONSTANTS {\n" - " __INTEGRITY_MinPageAlign = 16K\n" - " __INTEGRITY_MaxPageAlign = 16K\n" - " __INTEGRITY_LibCBaseAddress = \n"; - tl << dllbase << "\n"; - tl << "}\n" - "-sec\n" - "{\n" - " .picbase __INTEGRITY_LibCBaseAddress :\n" - " .text :\n" - " .syscall :\n" - " .intercall :\n" - " .interfunc :\n" - " .secinfo :\n" - " .rodata align(16) :\n" - " .fixaddr :\n" - " .fixtype :\n" - " .rombeg :\n" - " .textchecksum :\n" - " // The above sections may be large. Leave a bigger gap for large pages.\n" - " .pidbase align(__INTEGRITY_MaxPageAlign) :\n" - " .sdabase :\n" - " .data :\n" - " .toc :\n" - " .opd :\n" - " .datachecksum :\n" - " .bss align(__INTEGRITY_MinPageAlign) :\n" - " .heap :\n" - "}\n"; - tl.flush(); - dllbase += DLLOFFSET; - } - - QTextStream t(&Option::output); - QString primaryTarget(project->values("QMAKE_CXX").at(0).toQString()); - - pathtoremove += QDir::separator(); - filename.remove(qmake_getpwd()); - - //HEADER - t << "#!gbuild\n"; - - /* find the architecture out of the compiler name */ - if (filename.endsWith("projects.gpj")) { - primaryTarget.remove(0, 5); - t << "macro QT_BUILD_DIR=%expand_path(.)\n"; - t << "macro __OS_DIR=" << project->values("INTEGRITY_DIR").first() << "\n"; - t << "primaryTarget=" << primaryTarget << "_integrity.tgt\n"; - t << "customization=util/integrity/qt.bod\n"; - } - /* project type */ - if (project->first("TEMPLATE") == "app") { - t << "[Program]\n"; - if (isnativebin) { - t << "\t:binDir=bin\n"; - t << "\t-o " << strtarget << "\n"; - } else { - t << "\t:binDirRelative=.\n"; - t << "\t-o " << strtarget << "_app\n"; - } - } else if (project->first("TEMPLATE") == "lib") { - t << "[Library]\n"; - t << "\t:binDir=lib\n"; - t << "\t-o lib" << strtarget << ".a\n"; - } else if (project->first("TEMPLATE") == "subdirs") - t << "[Project]\n"; - else - t << project->first("TEMPLATE") << "\n"; - - /* compilations options */ - t << "\t:sourceDir=.\n"; - - t << "\t:outputDir=work" << relpath << "\n"; - if (filename.endsWith("projects.gpj")) { - t << "\t:sourceDir=work\n"; - t << "\t-Iwork\n"; - t << "\t-Llib\n"; - t << "\t"; - const ProStringList &l = project->values("QMAKE_CXXFLAGS"); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - if ((*it).startsWith("-")) - t << "\n\t" << (*it); - else - t << " " << (*it); - } - t << "\n"; - } - t << "\n"; - - t << varGlue("DEFINES", "\t-D", "\n\t-D", "\n"); - - t << "\t-I.\n\t-I" << specdir() << "\n"; - t << varGlue("INCLUDEPATH", "\t-I", "\n\t-I", "\n"); - t << "\t--cxx_include_directory .\n\t--cxx_include_directory " << specdir() << "\n"; - t << varGlue("INCLUDEPATH", "\t--cxx_include_directory ", "\n\t--cxx_include_directory ", "\n"); - - if (project->first("TEMPLATE") == "app") { - /* include linker flags if it's an application */ - static const char * const src[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "LIBS", 0 }; - for (int i = 0; src[i]; i++) { - /* skip target libraries for native tools */ - if (isnativebin && (i == 0)) - continue; - t << "\t"; - const ProStringList &l = project->values(src[i]); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - if ((*it).startsWith("-")) - t << "\n\t" << (*it); - else - t << " " << (*it); - } - t << "\n"; - } - } - - /* first subdirectories/subprojects */ - { - const ProStringList &l = project->values("SUBDIRS"); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - QString gpjname((*it).toQString()); - /* avoid native tools */ - if (nativebins.contains(gpjname.section("_", -1))) - continue; - const ProKey skey(*it + ".subdir"); - if (!project->first(skey).isEmpty()) - gpjname = project->first(skey).toQString(); - else - gpjname.replace("_", QDir::separator()); - gpjname += QDir::separator() + gpjname.section(QDir::separator(), -1); - gpjname += projectSuffix(); - /* make relative */ - if (!project->values("QT_SOURCE_TREE").isEmpty()) { - gpjname.replace(project->values("QT_SOURCE_TREE").first() + QDir::separator(), ""); - } - t << gpjname << "\n"; - } - } - - { - const ProStringList &l = project->values("RESOURCES"); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - QString tmpstr((*it).toQString()); - tmpstr.remove(pathtoremove); - t << tmpstr << "\t[Qt Resource]\n"; - tmpstr = tmpstr.section(".", -2, -1).section(QDir::separator(), -1); - tmpstr.remove(".qrc"); - t << "\t-name " << tmpstr << "\n"; - tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "qrc_"); - tmpstr.append(".cpp"); - t << "\t-o work/" << tmpstr << "\n"; - } - } - { - const ProStringList &l = project->values("FORMS"); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - QString tmpstr((*it).toQString()); - tmpstr.remove(pathtoremove); - t << tmpstr << "\t[Qt Dialog]\n"; - tmpstr = tmpstr.section(".", 0, 0).section(QDir::separator(), -1); - tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "ui_"); - tmpstr.remove(".ui"); - tmpstr.append(".h"); - t << "\t-o work/" << tmpstr << "\n"; - } - } - - /* source files for this project */ - static const char * const src[] = { "HEADERS", "SOURCES", 0 }; - for (int i = 0; src[i]; i++) { - const ProStringList &l = project->values(src[i]); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - if ((*it).isEmpty()) - continue; - /* native tools aren't preprocessed */ - if (!isnativebin) - t << writeOne((*it).toQString(), pathtoremove); - else - t << (*it).toQString().remove(pathtoremove) << "\n"; - } - } - t << "\n"; - - { - const ProStringList &l = project->values("GENERATED_SOURCES"); - for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - t << "work/" << (*it).toQString().section(QDir::separator(), -1) << "\n"; - } - } - - return true; -} - -QString GBuildMakefileGenerator::writeOne(QString filename, QString pathtoremove) -{ - QString s(""); - s += filename.remove(pathtoremove); - if (filename.endsWith(Option::h_ext.first())) { - QString corename(filename.section(QDir::separator(), -1)); - corename.remove(Option::h_ext.first()); - corename.append(Option::cpp_ext.first()); - corename.prepend(Option::h_moc_mod); - s += "\t[MOC/Qt Header]\n"; - s += "\t-o "; - s += "work/"; - s += corename; - s += "\n"; - } else if (filename.section(QDir::separator(), -1).startsWith("qrc_")) { - QString tmpstr(filename.section("/", -1).section(".", 0, -1).remove("qrc_").remove(".cpp")); - s += "\n\t:depends="; - s += tmpstr; - s += ".qrc"; - s += "\n"; - } else if (filename.endsWith(Option::cpp_ext.first())) { - QString tmpstr(filename.section("/", -1)); - QString filepath(pathtoremove); - if (!project->values("QT_SOURCE_TREE").isEmpty()) { - filepath.remove(project->first("QT_SOURCE_TREE").toQString()); - filepath.remove(0, 1); - } - s += "\n\t:preexecShellSafe='${QT_BUILD_DIR}/bin/moc "; - s += "-nn "; - s += varGlue("DEFINES", "-D", " -D", " "); - s += varGlue("INCLUDEPATH", "-I", " -I", " "); - s += filepath; - s += filename; - s += " -o "; - tmpstr.replace(Option::cpp_ext.first(), Option::cpp_moc_ext); - s += "work/"; - s += tmpstr; - s += "\n"; - } else - s += "\n"; - return s; -} - -bool -GBuildMakefileGenerator::openOutput(QFile &file, const QString &build) const -{ - Q_UNUSED(build) - debug_msg(1, "file is %s", file.fileName().toLatin1().constData()); - QFileInfo fi(file); - if (fi.filePath().isEmpty()) - file.setFileName(qmake_getpwd() + QDir::separator() + file.fileName()); - if (!file.fileName().endsWith(projectSuffix())) { - QString outputName(file.fileName()); - outputName += QDir::separator(); - outputName += fileInfo(project->projectFile()).baseName(); - outputName += projectSuffix(); - file.setFileName(outputName); - } - debug_msg(1, "file is %s", file.fileName().toLatin1().constData()); - bool ret = MakefileGenerator::openOutput(file, QString()); - return ret; -} - -QT_END_NAMESPACE diff --git a/qmake/generators/integrity/gbuild.h b/qmake/generators/integrity/gbuild.h deleted file mode 100644 index 2223975011..0000000000 --- a/qmake/generators/integrity/gbuild.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GBUILD_H -#define GBUILD_H - -#include "makefile.h" - -QT_BEGIN_NAMESPACE - -class GBuildMakefileGenerator : public MakefileGenerator -{ - virtual bool write(); - - QString projectSuffix() const { return QString(".gpj"); }; - QString writeOne(QString filename, QString pathtoremove = ""); - -public: - GBuildMakefileGenerator(); - ~GBuildMakefileGenerator(); - - virtual bool supportsMetaBuild() { return false; } - virtual bool openOutput(QFile &, const QString &) const; -protected: - bool doPrecompiledHeaders() const { return false; } - virtual bool doDepends() const { return true; } - ProStringList nativebins; - -}; - -inline GBuildMakefileGenerator::~GBuildMakefileGenerator() -{ } - -QT_END_NAMESPACE - -#endif // GBUILD_H diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 8f24c20712..3383e66ea6 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -151,7 +151,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) subdir += Option::dir_sep; tmp = subdir + tmp; } - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(tmp, true))); + QFileInfo fi(fileInfo(Option::normalizePath(tmp))); if(fi.exists()) { if(fi.isDir()) { QString profile = tmp; @@ -215,7 +215,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t" << project_key << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("lastKnownFileType", "wrapper.pb-project") << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(tmp_proj.first("TARGET") + projectSuffix())) << ";\n" + << "\t\t\t" << writeSettings("name", tmp_proj.first("TARGET") + projectSuffix()) << ";\n" << "\t\t\t" << writeSettings("path", pbxproj) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n" << "\t\t};\n"; @@ -283,7 +283,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t" << keyFor(grp_it.key()) << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n" + << "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n" << "\t\t};\n"; } @@ -307,7 +307,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) ProString name = l.at(i); const ProKey buildKey(name + ".build"); if (!project->isEmpty(buildKey)) { - const QString build = project->values(buildKey).first().toQString(); + const QString build = project->first(buildKey).toQString(); if (build.toLower() != configName.toLower()) continue; } @@ -344,7 +344,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_AGGREGATE_TARGET") << " = {\n" << "\t\t\t" << writeSettings("buildPhases", ProStringList(), SettingsAsList, 4) << ";\n" << "\t\t\tbuildSettings = {\n" - << "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->values("TARGET").first()) << ";\n" + << "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->first("TARGET")) << ";\n" << "\t\t\t};\n"; { ProStringList dependencies; @@ -354,8 +354,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t\t" << writeSettings("dependencies", dependencies, SettingsAsList, 4) << ";\n" } t << "\t\t\t" << writeSettings("isa", "PBXAggregateTarget", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", project->values("TARGET").first()) << ";\n" - << "\t\t\t" << writeSettings("productName", project->values("TARGET").first()) << ";\n" + << "\t\t\t" << writeSettings("name", project->first("TARGET")) << ";\n" + << "\t\t\t" << writeSettings("productName", project->first("TARGET")) << ";\n" << "\t\t};\n"; #endif @@ -455,8 +455,8 @@ ProjectBuilderSources::files(QMakeProject *project) const { QStringList ret = project->values(ProKey(key)).toQStringList(); if(key == "QMAKE_INTERNAL_INCLUDED_FILES") { - QString qtPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectivePaths) + '/'); - QString qtSrcPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectiveSourcePaths) + '/'); + QString qtPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/get")).toQString() + '/'); + QString qtSrcPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/src")).toQString() + '/'); QStringList newret; for(int i = 0; i < ret.size(); ++i) { @@ -558,6 +558,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -626,8 +627,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) const QStringList &files = fileFixify(sources.at(source).files(project)); for(int f = 0; f < files.count(); ++f) { QString file = files[f]; - if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0]) - file = file.mid(1, file.length()-2); if(!sources.at(source).compilerName().isNull() && !verifyExtraCompiler(sources.at(source).compilerName(), file)) continue; @@ -678,9 +677,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //source reference t << "\t\t" << src_key << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";\n"; + << "\t\t\t" << writeSettings("path", file) << ";\n"; if (name != file) - t << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n"; + t << "\t\t\t" << writeSettings("name", name) << ";\n"; t << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"; QString filetype = xcodeFiletypeForFilename(file); if (!filetype.isNull()) @@ -715,7 +714,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << keyFor(grp_it.key()) << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n" + << "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n" << "\t\t};\n"; } @@ -730,8 +729,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); QTextStream mkt(&mkf); writeHeader(mkt); - mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl; - mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl; + mkt << "MOC = " << var("QMAKE_MOC") << endl; + mkt << "UIC = " << var("QMAKE_UIC") << endl; mkt << "LEX = " << var("QMAKE_LEX") << endl; mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; mkt << "YACC = " << var("QMAKE_YACC") << endl; @@ -750,30 +749,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << endl; mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl; - mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl; - mkt << "PARSERS ="; - if(!project->isEmpty("YACCSOURCES")) { - const ProStringList &yaccs = project->values("YACCSOURCES"); - for (ProStringList::ConstIterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) { - QFileInfo fi(fileInfo((*yit).toQString())); - mkt << " " << fi.path() << Option::dir_sep << fi.baseName() - << Option::yacc_mod << Option::cpp_ext.first(); - } - } - if(!project->isEmpty("LEXSOURCES")) { - const ProStringList &lexs = project->values("LEXSOURCES"); - for (ProStringList::ConstIterator lit = lexs.begin(); lit != lexs.end(); ++lit) { - QFileInfo fi(fileInfo((*lit).toQString())); - mkt << " " << fi.path() << Option::dir_sep << fi.baseName() - << Option::lex_mod << Option::cpp_ext.first(); - } - } - mkt << "\n"; - mkt << "preprocess: $(PARSERS) compilers\n"; - mkt << "clean preprocess_clean: parser_clean compiler_clean\n\n"; - mkt << "parser_clean:\n"; - if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) - mkt << "\t-rm -f $(PARSERS)\n"; + mkt << "preprocess: compilers\n"; + mkt << "clean preprocess_clean: compiler_clean\n\n"; writeExtraTargets(mkt); if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) { mkt << "compilers:"; @@ -795,7 +772,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "\\\n\t"; ++added; const QString file_name = fileFixify(fn, Option::output_dir, Option::output_dir); - mkt << " " << replaceExtraCompilerVariables(Option::fixPathToTargetOS(tmp_out.first().toQString(), false), file_name, QString()); + mkt << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(tmp_out.first().toQString(), file_name, QString(), NoShell))); } } } @@ -818,6 +796,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -844,8 +823,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) bool remove = false; QString library, name; ProString opt = tmp[x].trimmed(); - if (opt.length() >= 2 && (opt.at(0) == '"' || opt.at(0) == '\'') && opt.endsWith(opt.at(0))) - opt = opt.mid(1, opt.length()-2); if(opt.startsWith("-L")) { QString r = opt.mid(2).toQString(); fixForOutput(r); @@ -881,10 +858,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString(); suffixSetting = "$(" + suffixSetting + ")"; if (!librarySuffix.isEmpty()) { - library = library.replace(librarySuffix, suffixSetting); - name = name.remove(librarySuffix); + library.replace(librarySuffix, suffixSetting); + name.remove(librarySuffix); } else { - library = library.replace(name, name + suffixSetting); + library.replace(name, name + suffixSetting); } } } @@ -951,14 +928,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) libdirs += path; } library = fileFixify(library); - QString filetype = xcodeFiletypeForFilename(library); QString key = keyFor(library); if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) { bool is_frmwrk = (library.endsWith(".framework")); t << "\t\t" << key << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n" - << "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";\n" + << "\t\t\t" << writeSettings("name", name) << ";\n" + << "\t\t\t" << writeSettings("path", library) << ";\n" << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(library)), SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"; if (is_frmwrk) @@ -993,14 +969,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QTextStream mkt(&mkf); writeHeader(mkt); mkt << "SUBLIBS= "; + // ### This is missing the parametrization found in unixmake2.cpp tmp = project->values("SUBLIBS"); for(int i = 0; i < tmp.count(); i++) - t << "tmp/lib" << tmp[i] << ".a "; + t << escapeFilePath("tmp/lib" + tmp[i] + ".a") << ' '; t << endl << endl; mkt << "sublibs: $(SUBLIBS)\n\n"; tmp = project->values("SUBLIBS"); for(int i = 0; i < tmp.count(); i++) - t << "tmp/lib" << tmp[i] << ".a:\n\t" + t << escapeFilePath("tmp/lib" + tmp[i] + ".a") + ":\n\t" << var(ProKey("MAKELIB" + tmp[i])) << endl << endl; mkt.flush(); mkf.close(); @@ -1017,6 +994,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", "Qt Sublibs") << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -1052,6 +1030,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\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\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } @@ -1064,7 +1043,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << key << " = {\n" << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n" + << "\t\t\t" << writeSettings("name", grp) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n" << "\t\t};\n"; } @@ -1077,7 +1056,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("files", project->values("QMAKE_PBX_BUILD_LIBRARIES"), SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXFrameworksBuildPhase", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n" + << "\t\t\t" << writeSettings("name", grp) << ";\n" << "\t\t};\n"; } @@ -1095,14 +1074,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\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\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } if (!project->isEmpty("DESTDIR")) { QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE"); QString destDir = project->first("DESTDIR").toQString(); - destDir = fixForOutput(destDir); - destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath(); + destDir = fileInfo(Option::normalizePath(destDir)).absoluteFilePath(); project->values("QMAKE_PBX_BUILDPHASES").append(phase_key); t << "\t\t" << phase_key << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n" @@ -1113,7 +1092,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("outputPaths", ProStringList(), SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" - << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";\n" + << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + IoUtils::shellQuoteUnix(destDir))) << ";\n" + << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" << "\t\t};\n"; } bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app"; @@ -1131,13 +1111,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //all files const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); for(int file = 0; file < files.count(); file++) { - QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir, FileFixifyAbsolute); + QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir, FileFixifyRelative); QString name = fn.split(Option::dir_sep).back(); QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn); bundle_file_refs += file_ref_key; t << "\t\t" << file_ref_key << " = {\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("path", escapeFilePath(fn)) << ";\n" + << "\t\t\t" << writeSettings("path", fn) << ";\n" << "\t\t\t" << writeSettings("name", name) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n" << "\t\t};\n"; @@ -1163,7 +1143,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << phase_key << " = {\n" << "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";\n" + << "\t\t\t" << writeSettings("dstPath", path) << ";\n" << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";\n" @@ -1187,8 +1167,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (copyBundleResources) { if (!project->isEmpty("ICON")) { ProString icon = project->first("ICON"); - if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0))) - icon = icon.mid(1, icon.length() - 2); bundle_resources_files += keyFor(icon + ".BUILDABLE"); } @@ -1201,7 +1179,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("files", bundle_resources_files, SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n" + << "\t\t\t" << writeSettings("name", grp) << ";\n" << "\t\t};\n"; } @@ -1226,9 +1204,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } else { t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.executable") << ";\n"; } - QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") : - qmake_getpwd()) + Option::dir_sep + targ; - t << "\t\t\t" << writeSettings("path", escapeFilePath(targ)) << ";\n"; + t << "\t\t\t" << writeSettings("path", targ) << ";\n"; } else { ProString lib = project->first("QMAKE_ORIG_TARGET"); if(project->isActiveConfig("staticlib")) { @@ -1256,7 +1232,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } else { t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.dylib") << ";\n"; } - t << "\t\t\t" << writeSettings("path", escapeFilePath(lib)) << ";\n"; + t << "\t\t\t" << writeSettings("path", lib) << ";\n"; } t << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n" << "\t\t};\n"; @@ -1276,7 +1252,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {\n" << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n" + << "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n" << "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n" << "\t\t};\n"; @@ -1322,14 +1298,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) else t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";\n"; } - t << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n" - << "\t\t\t" << writeSettings("productName", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n"; + t << "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n" + << "\t\t\t" << writeSettings("productName", project->first("QMAKE_ORIG_TARGET")) << ";\n"; } else { ProString lib = project->first("QMAKE_ORIG_TARGET"); if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) lib.prepend("lib"); - t << "\t\t\t" << writeSettings("name", escapeFilePath(lib)) << ";\n" - << "\t\t\t" << writeSettings("productName", escapeFilePath(lib)) << ";\n"; + t << "\t\t\t" << writeSettings("name", lib) << ";\n" + << "\t\t\t" << writeSettings("productName", lib) << ";\n"; if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";\n"; else if (project->isActiveConfig("staticlib")) @@ -1340,8 +1316,98 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.dynamic") << ";\n"; } if(!project->isEmpty("DESTDIR")) - t << "\t\t\t" << writeSettings("productInstallPath", escapeFilePath(project->first("DESTDIR"))) << ";\n"; + t << "\t\t\t" << writeSettings("productInstallPath", project->first("DESTDIR")) << ";\n"; t << "\t\t};\n"; + + // Test target for running Qt unit tests under XCTest + if (project->isActiveConfig("testcase") && project->isActiveConfig("app_bundle")) { + QString devNullFileReferenceKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_FILE_REFERENCE"); + t << "\t\t" << devNullFileReferenceKey << " = {\n" + << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("name", "/dev/null") << ";\n" + << "\t\t\t" << writeSettings("path", "/dev/null") << ";\n" + << "\t\t\t" << writeSettings("lastKnownFileType", "sourcecode.c.c") << ";\n" + << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n" + << "\t\t};\n"; + + QString devNullBuildFileKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_BUILD_FILE"); + t << "\t\t" << devNullBuildFileKey << " = {\n" + << "\t\t\t" << writeSettings("fileRef", devNullFileReferenceKey) << ";\n" + << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + QString dummySourceBuildPhaseKey = keyFor(pbx_dir + "QMAKE_PBX_DUMMY_SOURCE_BUILD_PHASE"); + t << "\t\t" << dummySourceBuildPhaseKey << " = {\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("files", devNullBuildFileKey, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("isa", "PBXSourcesBuildPhase", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + ProStringList testBundleBuildConfigs; + + ProString targetName = project->first("QMAKE_ORIG_TARGET"); + ProString testHost = "$(BUILT_PRODUCTS_DIR)/" + targetName + ".app/"; + if (!project->isActiveConfig("ios")) + testHost.append("Contents/MacOS/"); + testHost.append(targetName); + + static const char * const configs[] = { "Debug", "Release", 0 }; + for (int i = 0; configs[i]; i++) { + QString testBundleBuildConfig = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_" + configs[i]); + t << "\t\t" << testBundleBuildConfig << " = {\n" + << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n" + << "\t\t\tbuildSettings = {\n" + << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", project->first("QMAKE_XCODE_SPECDIR") + "/QtTest.plist") << ";\n" + << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", "") << ";\n" + << "\t\t\t\t" << writeSettings("TEST_HOST", testHost) << ";\n" + << "\t\t\t\t" << writeSettings("DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym") << ";\n" + << "\t\t\t};\n" + << "\t\t\t" << writeSettings("name", configs[i], SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + testBundleBuildConfigs.append(testBundleBuildConfig); + } + + QString testBundleBuildConfigurationListKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_LIST"); + t << "\t\t" << testBundleBuildConfigurationListKey << " = {\n" + << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("buildConfigurations", testBundleBuildConfigs, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("defaultConfigurationName", "Debug", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + QString primaryTargetDependencyKey = keyFor(pbx_dir + "QMAKE_PBX_PRIMARY_TARGET_DEP"); + t << "\t\t" << primaryTargetDependencyKey << " = {\n" + << "\t\t\t" << writeSettings("isa", "PBXTargetDependency", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("target", keyFor(pbx_dir + "QMAKE_PBX_TARGET")) << ";\n" + << "\t\t};\n"; + + QString testBundleReferenceKey = keyFor("QMAKE_TEST_BUNDLE_REFERENCE"); + t << "\t\t" << testBundleReferenceKey << " = {\n" + << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("explicitFileType", "wrapper.cfbundle") << ";\n" + << "\t\t\t" << writeSettings("includeInIndex", "0", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n" + << "\t\t};\n"; + + QString testTargetKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_TARGET"); + project->values("QMAKE_PBX_TARGETS").append(testTargetKey); + t << "\t\t" << testTargetKey << " = {\n" + << "\t\t\t" << writeSettings("buildPhases", dummySourceBuildPhaseKey, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("dependencies", primaryTargetDependencyKey, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("buildConfigurationList", testBundleBuildConfigurationListKey) << ";\n" + << "\t\t\t" << writeSettings("productType", "com.apple.product-type.bundle.unit-test") << ";\n" + << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("productReference", testBundleReferenceKey) << ";\n" + << "\t\t\t" << writeSettings("name", "Qt Test") << ";\n" + << "\t\t};\n"; + + QLatin1Literal testTargetID("TestTargetID"); + project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey + "_" + testTargetID)).append(keyFor(pbx_dir + "QMAKE_PBX_TARGET")); + project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey)).append(ProKey(testTargetID)); + } + //DEBUG/RELEASE QString defaultConfig; for(int as_release = 0; as_release < 2; as_release++) @@ -1361,14 +1427,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) ProString name = l.at(i); const ProKey buildKey(name + ".build"); if (!project->isEmpty(buildKey)) { - const QString build = project->values(buildKey).first().toQString(); + const QString build = project->first(buildKey).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)) - name = project->values(nkey).first(); + name = project->first(nkey); settings.insert(name.toQString(), value); } } @@ -1378,7 +1444,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) ProString lib = project->first("QMAKE_ORIG_TARGET"); if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) lib.prepend("lib"); - settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString())); + settings.insert("PRODUCT_NAME", lib.toQString()); } if (project->isActiveConfig("debug") != (bool)as_release) @@ -1421,22 +1487,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (plist_in_file.open(QIODevice::ReadOnly)) { QTextStream plist_in(&plist_in_file); QString plist_in_text = plist_in.readAll(); - plist_in_text = plist_in_text.replace("@ICON@", + plist_in_text.replace("@ICON@", (project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1))); if (project->first("TEMPLATE") == "app") { - plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString()); + plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString()); } else { - plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); + plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); } QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString(); if (bundlePrefix.isEmpty()) bundlePrefix = "com.yourcompany"; - plist_in_text = plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + "." + QLatin1String("${PRODUCT_NAME:rfc1034identifier}")); + plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + '.' + QLatin1String("${PRODUCT_NAME:rfc1034identifier}")); if (!project->values("VERSION").isEmpty()) { - plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + - project->first("VER_MIN")); + plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + project->first("VER_MIN")); } - plist_in_text = plist_in_text.replace("@TYPEINFO@", + plist_in_text.replace("@TYPEINFO@", (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString())); QFile plist_out_file("Info.plist"); @@ -1449,7 +1514,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } - t << "\t\t\t\t" << writeSettings("SYMROOT", escapeFilePath(qmake_getpwd())) << ";\n"; + t << "\t\t\t\t" << writeSettings("SYMROOT", qmake_getpwd()) << ";\n"; if (!project->isEmpty("DESTDIR")) { ProString dir = project->first("DESTDIR"); @@ -1485,11 +1550,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())); if (val.isEmpty() && var == "TB") val = "/usr/bin/"; - t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";\n"; + t << "\t\t\t\t" << writeSettings(var, val) << ";\n"; } if (!project->isEmpty("PRECOMPILED_HEADER")) { t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";\n" - << "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";\n"; + << "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", project->first("PRECOMPILED_HEADER")) << ";\n"; } t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH"), SettingsAsList, 5) << ";\n" << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";\n" @@ -1520,8 +1585,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", fixListForOutput("SUBLIBS") + fixListForOutput("QMAKE_LFLAGS") - + fixListForOutput("QMAKE_LIBS") - + fixListForOutput("QMAKE_LIBS_PRIVATE"), + + fixListForOutput(fixLibFlags("QMAKE_LIBS")) + + fixListForOutput(fixLibFlags("QMAKE_LIBS_PRIVATE")), SettingsAsList, 6) << ";\n"; } const ProStringList &archs = !project->values("QMAKE_XCODE_ARCHS").isEmpty() ? @@ -1529,7 +1594,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (!archs.isEmpty()) t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";\n"; if (!project->isEmpty("OBJECTS_DIR")) - t << "\t\t\t\t" << writeSettings("OBJROOT", escapeFilePath(project->first("OBJECTS_DIR").toQString())) << ";\n"; + t << "\t\t\t\t" << writeSettings("OBJROOT", project->first("OBJECTS_DIR")) << ";\n"; } else { if (project->first("TEMPLATE") == "app") { t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET").toQString())) << ";\n"; @@ -1541,7 +1606,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) ProString lib = project->first("QMAKE_ORIG_TARGET"); if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) lib.prepend("lib"); - t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";\n"; + t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", lib) << ";\n"; } } t << "\t\t\t};\n" @@ -1568,6 +1633,19 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t" << writeSettings("projectDirPath", ProStringList()) << ";\n" << "\t\t\t" << writeSettings("projectRoot", "") << ";\n" << "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";\n" + << "\t\t\t" << "attributes = {\n" + << "\t\t\t\tTargetAttributes = {\n"; + foreach (const ProString &target, project->values("QMAKE_PBX_TARGETS")) { + const ProStringList &attributes = project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target)); + if (attributes.isEmpty()) + continue; + t << "\t\t\t\t\t" << target << " = {\n"; + foreach (const ProString &attribute, attributes) + t << "\t\t\t\t\t\t" << writeSettings(attribute.toQString(), project->first(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target + "_" + attribute))) << ";\n"; + t << "\t\t\t\t\t};\n"; + } + t << "\t\t\t\t};\n" + << "\t\t\t};\n" << "\t\t};\n"; // FIXME: Deal with developmentRegion and knownRegions for QMAKE_PBX_ROOT @@ -1587,13 +1665,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QTextStream mkwrapt(&mkwrapf); writeHeader(mkwrapt); const char cleans[] = "preprocess_clean "; + const QString cmd = escapeFilePath(project->first("QMAKE_ORIG_TARGET") + projectSuffix() + "/") + " && " + pbxbuild(); mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" << "all:\n\t" - << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n" + << "cd " << cmd << "\n" << "install: all\n\t" - << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n" + << "cd " << cmd << " install\n" << "distclean clean: preprocess_clean\n\t" - << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean\n" + << "cd " << cmd << " clean\n" << (!did_preprocess ? cleans : "") << ":\n"; if(did_preprocess) mkwrapt << cleans << ":\n\t" @@ -1603,6 +1682,53 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } + // Scheme + { + QString xcodeSpecDir = project->first("QMAKE_XCODE_SPECDIR").toQString(); + + bool wroteCustomScheme = false; + + QString projectSharedSchemesPath = pbx_dir + "/xcshareddata/xcschemes"; + if (mkdir(projectSharedSchemesPath)) { + QString target = project->first("QMAKE_ORIG_TARGET").toQString(); + + QFile defaultSchemeFile(xcodeSpecDir + "/default.xcscheme"); + QFile outputSchemeFile(projectSharedSchemesPath + Option::dir_sep + target + ".xcscheme"); + + if (defaultSchemeFile.open(QIODevice::ReadOnly) + && outputSchemeFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + + QTextStream defaultSchemeStream(&defaultSchemeFile); + QString schemeData = defaultSchemeStream.readAll(); + + schemeData.replace("@QMAKE_ORIG_TARGET@", target); + schemeData.replace("@TARGET_PBX_KEY@", keyFor(pbx_dir + "QMAKE_PBX_TARGET")); + schemeData.replace("@TEST_BUNDLE_PBX_KEY@", keyFor("QMAKE_TEST_BUNDLE_REFERENCE")); + + QTextStream outputSchemeStream(&outputSchemeFile); + outputSchemeStream << schemeData; + + wroteCustomScheme = true; + } + } + + if (wroteCustomScheme) { + // Prevent Xcode from auto-generating schemes + QString workspaceSettingsFilename("WorkspaceSettings.xcsettings"); + QString workspaceSharedDataPath = pbx_dir + "/project.xcworkspace/xcshareddata"; + if (mkdir(workspaceSharedDataPath)) { + QFile::copy(xcodeSpecDir + Option::dir_sep + workspaceSettingsFilename, + workspaceSharedDataPath + Option::dir_sep + workspaceSettingsFilename); + } else { + wroteCustomScheme = false; + } + } + + if (!wroteCustomScheme) + warn_msg(WarnLogic, "Failed to generate schemes in '%s', " \ + "falling back to Xcode auto-generated schemes", qPrintable(projectSharedSchemesPath)); + } + qmake_setpwd(input_dir); return true; @@ -1693,7 +1819,6 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) c output += QDir::separator(); } output += QString("project.pbxproj"); - output = unescapeFilePath(output); file.setFileName(output); } bool ret = UnixMakefileGenerator::openOutput(file, build); @@ -1750,8 +1875,6 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const else version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; #endif - } else { - version_plist = version_plist.replace(QRegExp("\""), ""); } if (ret.isEmpty()) { QFile version_file(version_plist); @@ -1812,7 +1935,7 @@ int ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where) { int ret = 0; //absolute is the default.. - if(QDir::isRelativePath(unescapeFilePath(where))) + if (QDir::isRelativePath(where)) ret = 4; //relative return ret; } @@ -1838,26 +1961,6 @@ ProjectBuilderMakefileGenerator::pbxbuild() return (pbuilderVersion() >= 38 ? "xcodebuild" : "pbxbuild"); } -QString -ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const -{ -#if 1 - //in the middle of generating a Makefile! - if(writingUnixMakefileGenerator) - return UnixMakefileGenerator::escapeFilePath(path); - - //generating stuff for the xml file! - QString ret = path; - if(!ret.isEmpty()) { - ret = unescapeFilePath(ret); - debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); - } - return ret; -#else - return UnixMakefileGenerator::escapeFilePath(path); -#endif -} - static QString quotedStringLiteral(const QString &value) { QString result; diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index f5102d8c55..f517ce4bbd 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -72,8 +72,6 @@ public: virtual bool supportsMetaBuild() { return false; } virtual bool openOutput(QFile &, const QString &) const; protected: - virtual QString escapeFilePath(const QString &path) const; - ProString escapeFilePath(const ProString &path) const { return MakefileGenerator::escapeFilePath(path); } bool doPrecompiledHeaders() const { return false; } virtual bool doDepends() const { return writingUnixMakefileGenerator && UnixMakefileGenerator::doDepends(); } }; diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 804eab9ca7..f2decd71a5 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -45,7 +45,6 @@ #include <qhash.h> #include <qdebug.h> #include <qbuffer.h> -#include <qsettings.h> #include <qdatetime.h> #if defined(Q_OS_UNIX) @@ -62,6 +61,8 @@ QT_BEGIN_NAMESPACE +using namespace QMakeInternal; + bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const { int argv0 = -1; @@ -74,7 +75,7 @@ bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const if(a) *a = argv0; if(argv0 != -1) { - const QString c = Option::fixPathToLocalOS(cmdline.at(argv0), true); + const QString c = Option::normalizePath(cmdline.at(argv0)); if(exists(c)) return true; } @@ -89,50 +90,16 @@ QString MakefileGenerator::mkdir_p_asstring(const QString &dir, bool escape) con bool MakefileGenerator::mkdir(const QString &in_path) const { - QString path = Option::fixPathToLocalOS(in_path); + QString path = Option::normalizePath(in_path); if(QFile::exists(path)) return true; - QDir d; - if(path.startsWith(QDir::separator())) { - d.cd(QString(QDir::separator())); - path.remove(0, 1); - } - bool ret = true; -#ifdef Q_OS_WIN - bool driveExists = true; - if(!QDir::isRelativePath(path)) { - if(QFile::exists(path.left(3))) { - d.cd(path.left(3)); - path.remove(0, 3); - } else { - warn_msg(WarnLogic, "Cannot access drive '%s' (%s)", - path.left(3).toLatin1().data(), path.toLatin1().data()); - driveExists = false; - } - } - if(driveExists) -#endif - { - QStringList subs = path.split(QDir::separator()); - for(QStringList::Iterator subit = subs.begin(); subit != subs.end(); ++subit) { - if(!d.cd(*subit)) { - d.mkdir((*subit)); - if(d.exists((*subit))) { - d.cd((*subit)); - } else { - ret = false; - break; - } - } - } - } - return ret; + return QDir().mkpath(path); } // ** base makefile generator MakefileGenerator::MakefileGenerator() : - init_opath_already(false), init_already(false), no_io(false), project(0) + no_io(false), project(0) { } @@ -168,10 +135,6 @@ MakefileGenerator::verifyCompilers() void MakefileGenerator::initOutPaths() { - if(init_opath_already) - return; - verifyCompilers(); - init_opath_already = true; ProValueMap &v = project->variables(); //for shadow builds if(!v.contains("QMAKE_ABSOLUTE_SOURCE_PATH")) { @@ -249,9 +212,9 @@ MakefileGenerator::initOutPaths() for (ProStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { QString finp = fileFixify((*input).toQString(), Option::output_dir, Option::output_dir); *input = ProString(finp); - QString path = unescapeFilePath(replaceExtraCompilerVariables(tmp_out, finp, QString())); - path = Option::fixPathToTargetOS(path); - int slash = path.lastIndexOf(Option::dir_sep); + QString path = replaceExtraCompilerVariables(tmp_out, finp, QString(), NoShell); + path = Option::normalizePath(path); + int slash = path.lastIndexOf('/'); if(slash != -1) { path = path.left(slash); // Make out path only if it does not contain makefile variables @@ -267,7 +230,7 @@ MakefileGenerator::initOutPaths() if(!v["DESTDIR"].isEmpty()) { QDir d(v["DESTDIR"].first().toQString()); - if(Option::fixPathToLocalOS(d.absolutePath()) == Option::fixPathToLocalOS(Option::output_dir)) + if (Option::normalizePath(d.absolutePath()) == Option::normalizePath(Option::output_dir)) v.remove("DESTDIR"); } } @@ -314,8 +277,6 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString } if(!(flags & VPATH_NoFixify)) file = fileFixify(file, qmake_getpwd(), Option::output_dir); - if (file.at(0) == '\"' && file.at(file.length() - 1) == '\"') - file = file.mid(1, file.length() - 2); if(exists(file)) { ++val_it; @@ -332,8 +293,8 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString } for (ProStringList::Iterator vpath_it = vpath.begin(); vpath_it != vpath.end(); ++vpath_it) { - QString real_dir = Option::fixPathToLocalOS((*vpath_it).toQString()); - if(exists(real_dir + QDir::separator() + val)) { + QString real_dir = Option::normalizePath((*vpath_it).toQString()); + if (exists(real_dir + '/' + val)) { ProString dir = (*vpath_it); if(!dir.endsWith(Option::dir_sep)) dir += Option::dir_sep; @@ -413,11 +374,8 @@ MakefileGenerator::initCompiler(const MakefileGenerator::Compiler &comp) void MakefileGenerator::init() { - initOutPaths(); - if(init_already) - return; verifyCompilers(); - init_already = true; + initOutPaths(); ProValueMap &v = project->variables(); @@ -718,7 +676,7 @@ MakefileGenerator::init() const ProKey ikey(*it + ".input"); const ProKey vokey(*it + ".variable_out"); const ProStringList &config = project->values(ProKey(*it + ".CONFIG")); - const ProString &tmp_out = project->values(ProKey(*it + ".output")).first(); + const ProString &tmp_out = project->first(ProKey(*it + ".output")); if(tmp_out.isEmpty()) continue; if (config.indexOf("combine") != -1) { @@ -767,10 +725,9 @@ MakefileGenerator::init() if((*input).isEmpty()) continue; QString inpf = (*input).toQString(); - QString in = Option::fixPathToTargetOS(inpf, false); - if (!verifyExtraCompiler((*it).toQString(), in)) //verify + if (!verifyExtraCompiler((*it).toQString(), inpf)) //verify continue; - QString out = replaceExtraCompilerVariables(tmp_out.toQString(), inpf, QString()); + QString out = replaceExtraCompilerVariables(tmp_out.toQString(), inpf, QString(), NoShell); out = fileFixify(out, Option::output_dir, Option::output_dir); bool pre_dep = (config.indexOf("target_predeps") != -1); if (v.contains(vokey)) { @@ -814,7 +771,7 @@ MakefileGenerator::init() incDirs += v["INCLUDEPATH"]; QList<QMakeLocalFileName> deplist; for (ProStringList::Iterator it = incDirs.begin(); it != incDirs.end(); ++it) - deplist.append(QMakeLocalFileName(unescapeFilePath((*it).toQString()))); + deplist.append(QMakeLocalFileName((*it).toQString())); QMakeSourceFileInfo::setDependencyPaths(deplist); debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").toLatin1().constData()); //cache info @@ -860,7 +817,7 @@ MakefileGenerator::init() if(!project->isEmpty("TRANSLATIONS")) { ProStringList &trf = project->values("TRANSLATIONS"); for (ProStringList::Iterator it = trf.begin(); it != trf.end(); ++it) - (*it) = Option::fixPathToLocalOS((*it).toQString()); + (*it) = Option::fixPathToTargetOS((*it).toQString()); } //fix up the target deps @@ -869,7 +826,7 @@ MakefileGenerator::init() ProStringList &l = v[fixpaths[path]]; for (ProStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) - (*val_it) = escapeDependencyPath(Option::fixPathToTargetOS((*val_it).toQString(), false, false)); + (*val_it) = Option::fixPathToTargetOS((*val_it).toQString(), false, false); } } @@ -886,9 +843,9 @@ MakefileGenerator::init() if (exists(dep)) { out_deps.append(dep); } else { - QString dir, regex = Option::fixPathToLocalOS(dep); - if(regex.lastIndexOf(Option::dir_sep) != -1) { - dir = regex.left(regex.lastIndexOf(Option::dir_sep) + 1); + QString dir, regex = Option::normalizePath(dep); + if (regex.lastIndexOf('/') != -1) { + dir = regex.left(regex.lastIndexOf('/') + 1); regex.remove(0, dir.length()); } QStringList files = QDir(dir).entryList(QStringList(regex)); @@ -927,7 +884,7 @@ MakefileGenerator::processPrlFile(QString &file) meta_file = tmp; } // meta_file = fileFixify(meta_file); - QString real_meta_file = Option::fixPathToLocalOS(meta_file); + QString real_meta_file = Option::normalizePath(meta_file); if(!meta_file.isEmpty()) { QString f = fileFixify(real_meta_file, qmake_getpwd(), Option::output_dir); if(QMakeMetaInfo::libExists(f)) { @@ -947,7 +904,7 @@ MakefileGenerator::processPrlFile(QString &file) defs.append(def); if(try_replace_file && !libinfo.isEmpty("QMAKE_PRL_TARGET")) { QString dir; - int slsh = real_meta_file.lastIndexOf(Option::dir_sep); + int slsh = real_meta_file.lastIndexOf('/'); if(slsh != -1) dir = real_meta_file.left(slsh+1); file = libinfo.first("QMAKE_PRL_TARGET").toQString(); @@ -992,6 +949,21 @@ MakefileGenerator::processPrlFiles() qFatal("MakefileGenerator::processPrlFiles() called!"); } +static QString +qv(const ProString &val) +{ + return ' ' + QMakeEvaluator::quoteValue(val); +} + +static QString +qv(const ProStringList &val) +{ + QString ret; + foreach (const ProString &v, val) + ret += qv(v); + return ret; +} + void MakefileGenerator::writePrlFile(QTextStream &t) { @@ -1002,21 +974,21 @@ MakefileGenerator::writePrlFile(QTextStream &t) QString bdir = Option::output_dir; if(bdir.isEmpty()) bdir = qmake_getpwd(); - t << "QMAKE_PRL_BUILD_DIR = " << bdir << endl; + t << "QMAKE_PRL_BUILD_DIR =" << qv(bdir) << endl; - t << "QMAKE_PRO_INPUT = " << project->projectFile().section('/', -1) << endl; + t << "QMAKE_PRO_INPUT =" << qv(project->projectFile().section('/', -1)) << endl; if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) - t << "QMAKE_PRL_SOURCE_DIR = " << project->first("QMAKE_ABSOLUTE_SOURCE_PATH") << endl; - t << "QMAKE_PRL_TARGET = " << target << endl; + t << "QMAKE_PRL_SOURCE_DIR =" << qv(project->first("QMAKE_ABSOLUTE_SOURCE_PATH")) << endl; + t << "QMAKE_PRL_TARGET =" << qv(target) << endl; if(!project->isEmpty("PRL_EXPORT_DEFINES")) - t << "QMAKE_PRL_DEFINES = " << project->values("PRL_EXPORT_DEFINES").join(' ') << endl; + t << "QMAKE_PRL_DEFINES =" << qv(project->values("PRL_EXPORT_DEFINES")) << endl; if(!project->isEmpty("PRL_EXPORT_CFLAGS")) - t << "QMAKE_PRL_CFLAGS = " << project->values("PRL_EXPORT_CFLAGS").join(' ') << endl; + t << "QMAKE_PRL_CFLAGS =" << qv(project->values("PRL_EXPORT_CFLAGS")) << endl; if(!project->isEmpty("PRL_EXPORT_CXXFLAGS")) - t << "QMAKE_PRL_CXXFLAGS = " << project->values("PRL_EXPORT_CXXFLAGS").join(' ') << endl; + t << "QMAKE_PRL_CXXFLAGS =" << qv(project->values("PRL_EXPORT_CXXFLAGS")) << endl; if(!project->isEmpty("CONFIG")) - t << "QMAKE_PRL_CONFIG = " << project->values("CONFIG").join(' ') << endl; + t << "QMAKE_PRL_CONFIG =" << qv(project->values("CONFIG")) << endl; if(!project->isEmpty("TARGET_VERSION_EXT")) t << "QMAKE_PRL_VERSION = " << project->first("TARGET_VERSION_EXT") << endl; else if(!project->isEmpty("VERSION")) @@ -1029,9 +1001,9 @@ MakefileGenerator::writePrlFile(QTextStream &t) libs << "QMAKE_LIBS"; //obvious one if(project->isActiveConfig("staticlib")) libs << "QMAKE_LIBS_PRIVATE"; - t << "QMAKE_PRL_LIBS = "; + t << "QMAKE_PRL_LIBS ="; for (ProStringList::Iterator it = libs.begin(); it != libs.end(); ++it) - t << project->values((*it).toKey()).join(' ').replace('\\', "\\\\") << " "; + t << qv(project->values((*it).toKey())); t << endl; } } @@ -1079,9 +1051,9 @@ MakefileGenerator::writeProjectMakefile() writeSubTargets(t, targets, SubTargetsNoFlags); if(!project->isActiveConfig("no_autoqmake")) { + QString mkf = escapeDependencyPath(fileFixify(Option::output.fileName())); for(QList<SubTarget*>::Iterator it = targets.begin(); it != targets.end(); ++it) - t << (*it)->makefile << ": " << - Option::fixPathToTargetOS(fileFixify(Option::output.fileName())) << endl; + t << escapeDependencyPath((*it)->makefile) << ": " << mkf << endl; } qDeleteAll(targets); return true; @@ -1129,7 +1101,7 @@ MakefileGenerator::prlFileName(bool fixify) if(fixify) { if(!project->isEmpty("DESTDIR")) ret.prepend(project->first("DESTDIR").toQString()); - ret = Option::fixPathToLocalOS(fileFixify(ret, qmake_getpwd(), Option::output_dir)); + ret = fileFixify(ret, qmake_getpwd(), Option::output_dir); } return ret; } @@ -1176,30 +1148,16 @@ MakefileGenerator::writeObj(QTextStream &t, const char *src) t << escapeDependencyPath(dstf) << ": " << escapeDependencyPath(srcf) << " " << escapeDependencyPaths(findDependencies(srcf)).join(" \\\n\t\t"); - ProKey comp, cimp; + ProKey comp; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*sit).endsWith((*cppit))) { comp = "QMAKE_RUN_CXX"; - cimp = "QMAKE_RUN_CXX_IMP"; break; } } - if(comp.isEmpty()) { + if (comp.isEmpty()) comp = "QMAKE_RUN_CC"; - cimp = "QMAKE_RUN_CC_IMP"; - } - bool use_implicit_rule = !project->isEmpty(cimp); - use_implicit_rule = false; - if(use_implicit_rule) { - if(!project->isEmpty("OBJECTS_DIR")) { - use_implicit_rule = false; - } else { - int dot = (*sit).lastIndexOf('.'); - if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) - use_implicit_rule = false; - } - } - if (!use_implicit_rule && !project->isEmpty(comp)) { + if (!project->isEmpty(comp)) { QString p = var(comp); p.replace(stringSrc, escapeFilePath(srcf)); p.replace(stringObj, escapeFilePath(dstf)); @@ -1212,11 +1170,13 @@ MakefileGenerator::writeObj(QTextStream &t, const char *src) QString MakefileGenerator::filePrefixRoot(const QString &root, const QString &path) { - QString ret(root + path); + QString ret(path); if(path.length() > 2 && path[1] == ':') //c:\foo - ret = QString(path.mid(0, 2) + root + path.mid(2)); - while(ret.endsWith("\\")) - ret = ret.left(ret.length()-1); + ret.insert(2, root); + else + ret.prepend(root); + while (ret.endsWith('\\')) + ret.chop(1); return ret; } @@ -1245,7 +1205,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) QString dst; if (installConfigValues.indexOf("no_path") == -1 && installConfigValues.indexOf("dummy_install") == -1) { - dst = fileFixify(unescapeFilePath(project->first(pvar).toQString()), FileFixifyAbsolute, false); + dst = fileFixify(project->first(pvar).toQString(), FileFixifyAbsolute, false); if(!dst.endsWith(Option::dir_sep)) dst += Option::dir_sep; } @@ -1333,7 +1293,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false)))); continue; } - QString local_dirstr = Option::fixPathToLocalOS(dirstr, true); + QString local_dirstr = Option::normalizePath(dirstr); QStringList files = QDir(local_dirstr).entryList(QStringList(filestr), QDir::NoDotAndDotDot | QDir::AllEntries); if (installConfigValues.contains("no_check_exist") && files.isEmpty()) { @@ -1412,7 +1372,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) t << "uninstall_" << (*it) << ": FORCE"; for (int i = uninst.size(); --i >= 0; ) t << "\n\t" << uninst.at(i); - t << "\n\t-$(DEL_DIR) " << filePrefixRoot(root, dst) << " \n\n"; + t << "\n\t-$(DEL_DIR) " << escapeFilePath(filePrefixRoot(root, dst)) << " \n\n"; } t << endl; @@ -1425,8 +1385,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) debug_msg(1, "no definition for install %s: install target not created",(*it).toLatin1().constData()); } } - t << "install: " << var("INSTALLDEPS") << " " << all_installs - << " FORCE\n\nuninstall: " << all_uninstalls << " " << var("UNINSTALLDEPS") + t << "install:" << depVar("INSTALLDEPS") << ' ' << all_installs + << " FORCE\n\nuninstall: " << all_uninstalls << depVar("UNINSTALLDEPS") << " FORCE\n\n"; } @@ -1437,6 +1397,24 @@ MakefileGenerator::var(const ProKey &var) const } QString +MakefileGenerator::fileVar(const ProKey &var) const +{ + return val(escapeFilePaths(project->values(var))); +} + +QString +MakefileGenerator::fileVarList(const ProKey &var) const +{ + return valList(escapeFilePaths(project->values(var))); +} + +QString +MakefileGenerator::depVar(const ProKey &var) const +{ + return val(escapeDependencyPaths(project->values(var))); +} + +QString MakefileGenerator::val(const ProStringList &varList) const { return valGlue(varList, "", " ", ""); @@ -1457,6 +1435,12 @@ MakefileGenerator::varGlue(const ProKey &var, const QString &before, const QStri QString MakefileGenerator::fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const { + return valGlue(escapeFilePaths(project->values(var)), before, glue, after); +} + +QString +MakefileGenerator::fixFileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const +{ ProStringList varList; foreach (const ProString &val, project->values(var)) varList << escapeFilePath(Option::fixPathToTargetOS(val.toQString())); @@ -1519,12 +1503,11 @@ MakefileGenerator::createObjectList(const ProStringList &sources) objdir = project->first("OBJECTS_DIR").toQString(); for (ProStringList::ConstIterator it = sources.begin(); it != sources.end(); ++it) { QString sfn = (*it).toQString(); - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(sfn))); + QFileInfo fi(fileInfo(Option::normalizePath(sfn))); QString dir; if (project->isActiveConfig("object_parallel_to_source")) { // The source paths are relative to the output dir, but we need source-relative paths QString sourceRelativePath = fileFixify(sfn, qmake_getpwd(), Option::output_dir); - sourceRelativePath = Option::fixPathToTargetOS(sourceRelativePath, false); if (sourceRelativePath.startsWith(".." + Option::dir_sep)) sourceRelativePath = fileFixify(sourceRelativePath, FileFixifyAbsolute); @@ -1552,7 +1535,8 @@ MakefileGenerator::createObjectList(const ProStringList &sources) return ret; } -ReplaceExtraCompilerCacheKey::ReplaceExtraCompilerCacheKey(const QString &v, const QStringList &i, const QStringList &o) +ReplaceExtraCompilerCacheKey::ReplaceExtraCompilerCacheKey( + const QString &v, const QStringList &i, const QStringList &o, MakefileGenerator::ReplaceFor s) { static QString doubleColon = QLatin1String("::"); @@ -1569,11 +1553,13 @@ ReplaceExtraCompilerCacheKey::ReplaceExtraCompilerCacheKey(const QString &v, con ol.sort(); out = ol.join(doubleColon); } + forShell = s; } bool ReplaceExtraCompilerCacheKey::operator==(const ReplaceExtraCompilerCacheKey &f) const { return (hashCode() == f.hashCode() && + f.forShell == forShell && f.in == in && f.out == out && f.var == var && @@ -1582,10 +1568,11 @@ bool ReplaceExtraCompilerCacheKey::operator==(const ReplaceExtraCompilerCacheKey QString -MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const QStringList &in, const QStringList &out) +MakefileGenerator::replaceExtraCompilerVariables( + const QString &orig_var, const QStringList &in, const QStringList &out, ReplaceFor forShell) { //lazy cache - ReplaceExtraCompilerCacheKey cacheKey(orig_var, in, out); + ReplaceExtraCompilerCacheKey cacheKey(orig_var, in, out, forShell); QString cacheVal = extraCompilerVariablesCache.value(cacheKey); if(!cacheVal.isNull()) return cacheVal; @@ -1615,7 +1602,7 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const } else if(var == QLatin1String("QMAKE_FILE_BASE") || var == QLatin1String("QMAKE_FILE_IN_BASE")) { //filePath = true; for(int i = 0; i < in.size(); ++i) { - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(in.at(i)))); + QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QString base = fi.completeBaseName(); if(base.isNull()) base = fi.fileName(); @@ -1624,7 +1611,7 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const } else if(var == QLatin1String("QMAKE_FILE_EXT")) { filePath = true; for(int i = 0; i < in.size(); ++i) { - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(in.at(i)))); + QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QString ext; // Ensure complementarity with QMAKE_FILE_BASE int baseLen = fi.completeBaseName().length(); @@ -1637,11 +1624,11 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const } else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) { filePath = true; for(int i = 0; i < in.size(); ++i) - val += fileInfo(Option::fixPathToLocalOS(in.at(i))).path(); + val += fileInfo(Option::normalizePath(in.at(i))).path(); } else if(var == QLatin1String("QMAKE_FILE_NAME") || var == QLatin1String("QMAKE_FILE_IN")) { filePath = true; for(int i = 0; i < in.size(); ++i) - val += fileInfo(Option::fixPathToLocalOS(in.at(i))).filePath(); + val += fileInfo(Option::normalizePath(in.at(i))).filePath(); } } @@ -1653,11 +1640,11 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const } else if(var == QLatin1String("QMAKE_FILE_OUT")) { filePath = true; for(int i = 0; i < out.size(); ++i) - val += fileInfo(Option::fixPathToLocalOS(out.at(i))).filePath(); + val += fileInfo(Option::normalizePath(out.at(i))).filePath(); } else if(var == QLatin1String("QMAKE_FILE_OUT_BASE")) { //filePath = true; for(int i = 0; i < out.size(); ++i) { - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(out.at(i)))); + QFileInfo fi(fileInfo(Option::normalizePath(out.at(i)))); QString base = fi.completeBaseName(); if(base.isNull()) base = fi.fileName(); @@ -1672,12 +1659,14 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const if(!val.isEmpty()) { QString fullVal; - if(filePath) { + if (filePath && forShell != NoShell) { for(int i = 0; i < val.size(); ++i) { - const QString file = Option::fixPathToTargetOS(unescapeFilePath(val.at(i)), false); if(!fullVal.isEmpty()) fullVal += " "; - fullVal += escapeFilePath(file); + if (forShell == LocalShell) + fullVal += IoUtils::shellQuote(Option::fixPathToLocalOS(val.at(i), false)); + else + fullVal += escapeFilePath(Option::fixPathToTargetOS(val.at(i), false)); } } else { fullVal = val.join(' '); @@ -1699,7 +1688,7 @@ MakefileGenerator::verifyExtraCompiler(const ProString &comp, const QString &fil { if(noIO()) return false; - const QString file = Option::fixPathToLocalOS(file_unfixed); + const QString file = Option::normalizePath(file_unfixed); const ProStringList &config = project->values(ProKey(comp + ".CONFIG")); if (config.indexOf("moc_verify") != -1) { @@ -1712,7 +1701,7 @@ MakefileGenerator::verifyExtraCompiler(const ProString &comp, const QString &fil } } } else if (config.indexOf("function_verify") != -1) { - ProString tmp_out = project->values(ProKey(comp + ".output")).first(); + ProString tmp_out = project->first(ProKey(comp + ".output")); if(tmp_out.isEmpty()) return false; ProStringList verify_function = project->values(ProKey(comp + ".verify_function")); @@ -1741,10 +1730,10 @@ MakefileGenerator::verifyExtraCompiler(const ProString &comp, const QString &fil if((*input).isEmpty()) continue; QString inpf = (*input).toQString(); - QString in = fileFixify(Option::fixPathToTargetOS(inpf, false)); + QString in = fileFixify(inpf); if(in == file) { bool pass = project->test(verify.toKey(), - QList<ProStringList>() << ProStringList(replaceExtraCompilerVariables(tmp_out.toQString(), inpf, QString())) << + QList<ProStringList>() << ProStringList(replaceExtraCompilerVariables(tmp_out.toQString(), inpf, QString(), NoShell)) << ProStringList(file)); if(invert) pass = !pass; @@ -1757,12 +1746,12 @@ MakefileGenerator::verifyExtraCompiler(const ProString &comp, const QString &fil } } } else if (config.indexOf("verify") != -1) { - QString tmp_out = project->values(ProKey(comp + ".output")).first().toQString(); + QString tmp_out = project->first(ProKey(comp + ".output")).toQString(); if(tmp_out.isEmpty()) return false; const QString tmp_cmd = project->values(ProKey(comp + ".commands")).join(' '); if (config.indexOf("combine") != -1) { - QString cmd = replaceExtraCompilerVariables(tmp_cmd, QString(), tmp_out); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, QString(), tmp_out, LocalShell); if(system(cmd.toLatin1().constData())) return false; } else { @@ -1773,10 +1762,10 @@ MakefileGenerator::verifyExtraCompiler(const ProString &comp, const QString &fil if((*input).isEmpty()) continue; QString inpf = (*input).toQString(); - QString in = fileFixify(Option::fixPathToTargetOS(inpf, false)); + QString in = fileFixify(inpf); if(in == file) { - QString out = replaceExtraCompilerVariables(tmp_out, inpf, QString()); - QString cmd = replaceExtraCompilerVariables(tmp_cmd, in, out); + QString out = replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, in, out, LocalShell); if(system(cmd.toLatin1().constData())) return false; break; @@ -1841,8 +1830,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) for (ProStringList::ConstIterator it2 = comp_inputs.begin(); it2 != comp_inputs.end(); ++it2) { const ProStringList &tmp = project->values((*it2).toKey()); for (ProStringList::ConstIterator input = tmp.begin(); input != tmp.end(); ++input) { - QString in = Option::fixPathToTargetOS((*input).toQString(), false); - if(verifyExtraCompiler((*it), in)) + if (verifyExtraCompiler((*it), (*input).toQString())) tmp_inputs.append((*input)); } } @@ -1853,16 +1841,19 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if (config.indexOf("combine") != -1) { // compilers with a combined input only have one output QString input = project->first(ProKey(*it + ".output")).toQString(); - t << " " << escapeDependencyPath(Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, input, QString()))); + t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell))); } else { for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { - t << " " << escapeDependencyPath(Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString()))); + t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell))); } } t << endl; if (config.indexOf("no_clean") == -1) { - QString tmp_clean = project->values(ProKey(*it + ".clean")).join(' '); + const ProStringList &raw_clean = project->values(ProKey(*it + ".clean")); + QString tmp_clean = escapeFilePaths(raw_clean).join(' '); QString tmp_clean_cmds = project->values(ProKey(*it + ".clean_commands")).join(' '); if(!tmp_inputs.isEmpty()) clean_targets += QString("compiler_" + (*it) + "_clean "); @@ -1875,34 +1866,37 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) wrote_clean_cmds = true; } if(tmp_clean.isEmpty()) - tmp_clean = tmp_out; + tmp_clean = escapeFilePath(tmp_out); if(tmp_clean.indexOf("${QMAKE_") == -1) { t << "\n\t-$(DEL_FILE) " << tmp_clean; wrote_clean = true; } if(!wrote_clean_cmds || !wrote_clean) { - ProStringList cleans; + QStringList q_raw_clean = raw_clean.toQStringList(); + QStringList cleans; const QString del_statement("-$(DEL_FILE)"); if(!wrote_clean) { - if(project->isActiveConfig("no_delete_multiple_files")) { - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { - QString tinp = (*input).toQString(); - cleans.append(" " + Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_clean, tinp, - replaceExtraCompilerVariables(tmp_out, tinp, QString())))); + QStringList dels; + for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + QString tinp = (*input).toQString(); + QString out = replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell); + foreach (const QString &rc, q_raw_clean) { + dels << ' ' + escapeFilePath(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(rc, tinp, out, NoShell), false)); } + } + if(project->isActiveConfig("no_delete_multiple_files")) { + cleans = dels; } else { - QString files, file; + QString files; const int commandlineLimit = 2047; // NT limit, expanded - for(int input = 0; input < tmp_inputs.size(); ++input) { - QString tinp = tmp_inputs.at(input).toQString(); - file = " " + replaceExtraCompilerVariables(tmp_clean, tinp, - replaceExtraCompilerVariables(tmp_out, tinp, QString())); + foreach (const QString &file, dels) { if(del_statement.length() + files.length() + qMax(fixEnvVariables(file).length(), file.length()) > commandlineLimit) { cleans.append(files); files.clear(); } - files += Option::fixPathToTargetOS(file); + files += file; } if(!files.isEmpty()) cleans.append(files); @@ -1914,7 +1908,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { QString tinp = (*input).toQString(); t << "\n\t" << replaceExtraCompilerVariables(tmp_clean_cmds, tinp, - replaceExtraCompilerVariables(tmp_out, tinp, QString())); + replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell), TargetShell); } } } @@ -1936,7 +1930,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) inputs += Option::fixPathToTargetOS(inpf, false); if(!tmp_dep_cmd.isEmpty() && doDepends()) { char buff[256]; - QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out); + QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell); dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd); if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) { QString indeps; @@ -1948,6 +1942,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } QT_PCLOSE(proc); if(!indeps.isEmpty()) { + // ### This is basically fubar. Add 'lines' flag to CONFIG? QStringList dep_cmd_deps = indeps.replace('\n', ' ').simplified().split(' '); for(int i = 0; i < dep_cmd_deps.count(); ++i) { QString &file = dep_cmd_deps[i]; @@ -1959,8 +1954,8 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths(); for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin(); dit != depdirs.end(); ++dit) { - if (exists((*dit).real() + Option::dir_sep + file)) { - localFile = (*dit).local() + Option::dir_sep + file; + if (exists((*dit).local() + '/' + file)) { + localFile = (*dit).local() + '/' + file; break; } } @@ -1998,8 +1993,8 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if (inputs.isEmpty()) continue; - QString out = replaceExtraCompilerVariables(tmp_out, QString(), QString()); - QString cmd = replaceExtraCompilerVariables(tmp_cmd, escapeFilePaths(inputs), QStringList() << out); + QString out = replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, inputs, QStringList() << out, TargetShell); t << escapeDependencyPath(Option::fixPathToTargetOS(out)) << ":"; // compiler.CONFIG+=explicit_dependencies means that ONLY compiler.depends gets to cause Makefile dependencies if (config.indexOf("explicit_dependencies") != -1) { @@ -2014,20 +2009,20 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QString inpf = (*input).toQString(); QString in = Option::fixPathToTargetOS(inpf, false); QStringList deps = findDependencies(inpf); - deps += escapeDependencyPath(in); - QString out = unescapeFilePath(Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, inpf, QString()))); + deps << in; + QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell)); if(!tmp_dep.isEmpty()) { QStringList pre_deps = fileFixify(tmp_dep, Option::output_dir, Option::output_dir); for(int i = 0; i < pre_deps.size(); ++i) - deps += replaceExtraCompilerVariables(pre_deps.at(i), inpf, out); + deps << replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell); } - QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, LocalShell); // NOTE: The var -> QMAKE_COMP_var replace feature is unsupported, do not use! for (ProStringList::ConstIterator it3 = vars.constBegin(); it3 != vars.constEnd(); ++it3) cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); if(!tmp_dep_cmd.isEmpty() && doDepends()) { char buff[256]; - QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, out); + QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, out, LocalShell); dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd); if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) { QString indeps; @@ -2039,6 +2034,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } QT_PCLOSE(proc); if(!indeps.isEmpty()) { + // ### This is basically fubar. Add 'lines' flag to CONFIG? QStringList dep_cmd_deps = indeps.replace('\n', ' ').simplified().split(' '); for(int i = 0; i < dep_cmd_deps.count(); ++i) { QString &file = dep_cmd_deps[i]; @@ -2050,8 +2046,8 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths(); for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin(); dit != depdirs.end(); ++dit) { - if (exists((*dit).real() + Option::dir_sep + file)) { - localFile = (*dit).local() + Option::dir_sep + file; + if (exists((*dit).local() + '/' + file)) { + localFile = (*dit).local() + '/' + file; break; } } @@ -2116,7 +2112,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } for(int i = 0; i < deps.size(); ) { QString &dep = deps[i]; - dep = Option::fixPathToTargetOS(unescapeFilePath(dep), false); + dep = Option::fixPathToTargetOS(dep, false); if(out == dep) deps.removeAt(i); else @@ -2236,13 +2232,6 @@ MakefileGenerator::writeDefaultVariables(QTextStream &t) t << "MOVE = " << var("QMAKE_MOVE") << endl; } -QString MakefileGenerator::fixifySpecdir(const QString &spec, const QString &outdir) -{ - if (QFileInfo(spec).isAbsolute()) - return fileFixify(spec, outdir); - return spec; -} - QString MakefileGenerator::buildArgs() { QString ret; @@ -2262,7 +2251,7 @@ QString MakefileGenerator::build_args(const QString &outdir) ret += buildArgs(); //output - QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); + QString ofile = fileFixify(Option::output.fileName()); if(!ofile.isEmpty() && ofile != project->first("QMAKE_MAKEFILE")) ret += " -o " + escapeFilePath(ofile); @@ -2287,7 +2276,7 @@ MakefileGenerator::writeHeader(QTextStream &t) QString ofile = Option::fixPathToTargetOS(Option::output.fileName()); if (ofile.lastIndexOf(Option::dir_sep) != -1) ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1); - t << "MAKEFILE = " << ofile << endl << endl; + t << "MAKEFILE = " << escapeFilePath(ofile) << endl << endl; } QList<MakefileGenerator::SubTarget*> @@ -2300,7 +2289,7 @@ MakefileGenerator::findSubDirsSubTargets() const ProString ofile = subdirs[subdir]; QString oname = ofile.toQString(); QString fixedSubdir = oname; - fixedSubdir = fixedSubdir.replace(QRegExp("[^a-zA-Z0-9_]"),"-"); + fixedSubdir.replace(QRegExp("[^a-zA-Z0-9_]"),"-"); SubTarget *st = new SubTarget; st->name = oname; @@ -2365,12 +2354,12 @@ MakefileGenerator::findSubDirsSubTargets() const if(subdirs[subDep] == depends.at(depend)) { QString subName = subdirs[subDep].toQString(); QString fixedSubDep = subName; - fixedSubDep = fixedSubDep.replace(QRegExp("[^a-zA-Z0-9_]"),"-"); + fixedSubDep.replace(QRegExp("[^a-zA-Z0-9_]"),"-"); const ProKey dtkey(fixedSubDep + ".target"); if (!project->isEmpty(dtkey)) { st->depends += project->first(dtkey); } else { - QString d = Option::fixPathToLocalOS(subName); + QString d = Option::fixPathToTargetOS(subName); const ProKey dfkey(fixedSubDep + ".file"); if (!project->isEmpty(dfkey)) { d = project->first(dfkey).toQString(); @@ -2396,7 +2385,7 @@ MakefileGenerator::findSubDirsSubTargets() const st->target = project->first(tkey).toQString(); } else { st->target = "sub-" + file; - st->target = st->target.replace(QRegExp("[^a-zA-Z0-9_]"),"-"); + st->target.replace(QRegExp("[^a-zA-Z0-9_]"), "-"); } } } @@ -2477,8 +2466,8 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT out_directory = Option::output_dir + out_directory.mid(abs_source_path.length()); QString out_directory_cdin = out_directory.isEmpty() ? "\n\t" - : "\n\tcd " + out_directory + " && "; - QString makefilein = " -f " + subtarget->makefile; + : "\n\tcd " + escapeFilePath(out_directory) + " && "; + QString makefilein = " -f " + escapeFilePath(subtarget->makefile); //qmake it QString out; @@ -2488,6 +2477,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); if(out.startsWith(in_directory)) out = out.mid(in_directory.length()); + out = escapeFilePath(out); t << subtarget->target << "-qmake_all: "; if (flags & SubTargetOrdered) { if (target) @@ -2581,19 +2571,19 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT t << " " << targetRule; } if(suffix == "all" || suffix == "make_first") - t << varGlue("ALL_DEPS"," "," ",""); + t << depVar("ALL_DEPS"); if(suffix == "clean") - t << varGlue("CLEAN_DEPS"," "," ",""); + t << depVar("CLEAN_DEPS"); else if (suffix == "distclean") - t << varGlue("DISTCLEAN_DEPS"," "," ",""); + t << depVar("DISTCLEAN_DEPS"); t << " FORCE\n"; if(suffix == "clean") { - t << fileVarGlue("QMAKE_CLEAN", "\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", "\n"); + t << fixFileVarGlue("QMAKE_CLEAN", "\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", "\n"); } else if(suffix == "distclean") { - QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); + QString ofile = fileFixify(Option::output.fileName()); if(!ofile.isEmpty()) - t << "\t-$(DEL_FILE) " << ofile << endl; - t << fileVarGlue("QMAKE_DISTCLEAN", "\t-$(DEL_FILE) ", " ", "\n"); + t << "\t-$(DEL_FILE) " << escapeFilePath(ofile) << endl; + t << fixFileVarGlue("QMAKE_DISTCLEAN", "\t-$(DEL_FILE) ", " ", "\n"); } } @@ -2612,7 +2602,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT QString dep = var(ProKey(*dep_it + ".target")); if(dep.isEmpty()) dep = Option::fixPathToTargetOS((*dep_it).toQString(), false); - deps += " " + dep; + deps += ' ' + escapeDependencyPath(dep); } if (config.indexOf("recursive") != -1) { QSet<QString> recurse; @@ -2638,8 +2628,8 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT continue; QString out_directory_cdin = out_directory.isEmpty() ? "\n\t" - : "\n\tcd " + out_directory + " && "; - QString makefilein = " -f " + subtarget->makefile; + : "\n\tcd " + escapeFilePath(out_directory) + " && "; + QString makefilein = " -f " + escapeFilePath(subtarget->makefile); QString out; QString in; @@ -2648,6 +2638,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); if (out.startsWith(in_directory)) out = out.mid(in_directory.length()); + out = escapeFilePath(out); } //write the rule/depends @@ -2693,16 +2684,16 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT void MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll) { - QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); + QString ofile = fileFixify(Option::output.fileName()); if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { - QStringList files = fileFixify(Option::mkfile::project_files); + QStringList files = escapeFilePaths(fileFixify(Option::mkfile::project_files)); t << escapeDependencyPath(project->first("QMAKE_INTERNAL_PRL_FILE").toQString()) << ": \n\t" << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(' ') << endl; } QString qmake = build_args(); if(!ofile.isEmpty() && !project->isActiveConfig("no_autoqmake")) { - t << escapeFilePath(ofile) << ": " + t << escapeDependencyPath(ofile) << ": " << escapeDependencyPath(fileFixify(project->projectFile())) << " "; if (Option::globals->do_cache) { if (!project->confFile().isEmpty()) @@ -2711,11 +2702,11 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll) t << escapeDependencyPath(fileFixify(project->cacheFile())) << " "; } if(!specdir().isEmpty()) { - if(exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"qmake.conf"))) + if (exists(Option::normalizePath(specdir() + "/qmake.conf"))) t << escapeDependencyPath(specdir() + Option::dir_sep + "qmake.conf") << " "; } - const ProStringList &included = project->values("QMAKE_INTERNAL_INCLUDED_FILES"); - t << escapeDependencyPaths(included).join(" \\\n\t\t") << "\n\t" + const ProStringList &included = escapeDependencyPaths(project->values("QMAKE_INTERNAL_INCLUDED_FILES")); + t << included.join(" \\\n\t\t") << "\n\t" << qmake << endl; for(int include = 0; include < included.size(); ++include) { const ProString &i = included.at(include); @@ -2750,19 +2741,22 @@ MakefileGenerator::fileInfo(QString file) const return fi; } -QString -MakefileGenerator::unescapeFilePath(const QString &path) const +ProStringList +MakefileGenerator::fixLibFlags(const ProKey &var) { - QString ret = path; - ret.replace(QLatin1String("\\ "), QLatin1String(" ")); - ret.remove(QLatin1Char('\"')); + ProStringList in = project->values(var); + ProStringList ret; + + ret.reserve(in.length()); + foreach (const ProString &v, in) + ret << fixLibFlag(v); return ret; } -ProString -MakefileGenerator::unescapeFilePath(const ProString &path) const +ProString MakefileGenerator::fixLibFlag(const ProString &) { - return ProString(unescapeFilePath(path.toQString())); + qFatal("MakefileGenerator::fixLibFlag() called"); + return ProString(); } ProString @@ -2789,6 +2783,12 @@ MakefileGenerator::escapeFilePaths(const ProStringList &paths) const return ret; } +ProString +MakefileGenerator::escapeDependencyPath(const ProString &path) const +{ + return ProString(escapeDependencyPath(path.toQString())); +} + QStringList MakefileGenerator::escapeDependencyPaths(const QStringList &paths) const { @@ -2808,24 +2808,6 @@ MakefileGenerator::escapeDependencyPaths(const ProStringList &paths) const } QStringList -MakefileGenerator::unescapeFilePaths(const QStringList &paths) const -{ - QStringList ret; - for(int i = 0; i < paths.size(); ++i) - ret.append(unescapeFilePath(paths.at(i))); - return ret; -} - -ProStringList -MakefileGenerator::unescapeFilePaths(const ProStringList &paths) const -{ - ProStringList ret; - for (int i = 0; i < paths.size(); ++i) - ret.append(unescapeFilePath(paths.at(i))); - return ret; -} - -QStringList MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, FileFixifyType fix, bool canon) const { @@ -2845,7 +2827,7 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q { if(file.isEmpty()) return file; - QString ret = unescapeFilePath(file); + QString ret = file; //do the fixin' QString orig_file = ret; @@ -2875,7 +2857,7 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q out_dir = out_fi.canonicalFilePath(); } - QString qfile(Option::fixPathToLocalOS(ret, true, canon)); + QString qfile(Option::normalizePath(ret)); QFileInfo qfileinfo(fileInfo(qfile)); if(out_dir != in_dir || !qfileinfo.isRelative()) { if(qfileinfo.isRelative()) { @@ -3004,7 +2986,7 @@ MakefileGenerator::findFileForDep(const QMakeLocalFileName &dep, const QMakeLoca } } { //is it from an EXTRA_TARGET - const QString dep_basename = dep.local().section(Option::dir_sep, -1); + const QString dep_basename = dep.local().section('/', -1); const ProStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); for (ProStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) { QString targ = var(ProKey(*it + ".target")); @@ -3018,7 +3000,7 @@ MakefileGenerator::findFileForDep(const QMakeLocalFileName &dep, const QMakeLoca } } { //is it from an EXTRA_COMPILER - const QString dep_basename = dep.local().section(Option::dir_sep, -1); + const QString dep_basename = dep.local().section('/', -1); const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { const ProString &tmp_out = project->first(ProKey(*it + ".output")); @@ -3028,8 +3010,8 @@ MakefileGenerator::findFileForDep(const QMakeLocalFileName &dep, const QMakeLoca for (ProStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { const ProStringList &inputs = project->values((*it2).toKey()); for (ProStringList::ConstIterator input = inputs.begin(); input != inputs.end(); ++input) { - QString out = Option::fixPathToTargetOS(unescapeFilePath( - replaceExtraCompilerVariables(tmp_out.toQString(), (*input).toQString(), QString()))); + QString out = Option::fixPathToTargetOS( + replaceExtraCompilerVariables(tmp_out.toQString(), (*input).toQString(), QString(), NoShell)); if (out == dep.real() || out.section(Option::dir_sep, -1) == dep_basename) { ret = QMakeLocalFileName(fileFixify(out, qmake_getpwd(), Option::output_dir)); goto found_dep_from_heuristic; @@ -3148,7 +3130,7 @@ MakefileGenerator::pkgConfigFileName(bool fixify) if(fixify) { if(QDir::isRelativePath(ret) && !project->isEmpty("DESTDIR")) ret.prepend(project->first("DESTDIR").toQString()); - ret = Option::fixPathToLocalOS(fileFixify(ret, qmake_getpwd(), Option::output_dir)); + ret = fileFixify(ret, qmake_getpwd(), Option::output_dir); } return ret; } @@ -3158,7 +3140,7 @@ MakefileGenerator::pkgConfigPrefix() const { if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX")) return project->first("QMAKE_PKGCONFIG_PREFIX").toQString(); - return QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::FinalPaths); + return project->propertyValue(ProKey("QT_INSTALL_PREFIX")).toQString(); } QString @@ -3166,7 +3148,7 @@ MakefileGenerator::pkgConfigFixPath(QString path) const { QString prefix = pkgConfigPrefix(); if(path.startsWith(prefix)) - path = path.replace(prefix, "${prefix}"); + path.replace(prefix, "${prefix}"); return path; } @@ -3259,9 +3241,9 @@ MakefileGenerator::writePkgConfigFile() } ProString bundle; if (!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME")) - bundle = unescapeFilePath(project->first("QMAKE_FRAMEWORK_BUNDLE_NAME")); + bundle = project->first("QMAKE_FRAMEWORK_BUNDLE_NAME"); else - bundle = unescapeFilePath(project->first("TARGET")); + bundle = project->first("TARGET"); int suffix = bundle.lastIndexOf(".framework"); if (suffix != -1) bundle = bundle.left(suffix); @@ -3269,11 +3251,11 @@ MakefileGenerator::writePkgConfigFile() } else { if (!project->values("QMAKE_DEFAULT_LIBDIRS").contains(libDir)) t << "-L${libdir} "; - pkgConfiglibName = "-l" + unescapeFilePath(project->first("QMAKE_ORIG_TARGET")); + pkgConfiglibName = "-l" + project->first("QMAKE_ORIG_TARGET"); if (project->isActiveConfig("shared")) pkgConfiglibName += project->first("TARGET_VERSION_EXT").toQString(); } - t << pkgConfiglibName << " \n"; + t << shellQuote(pkgConfiglibName) << " \n"; ProStringList libs; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) { @@ -3285,7 +3267,7 @@ MakefileGenerator::writePkgConfigFile() libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread? t << "Libs.private: "; for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) { - t << project->values((*it).toKey()).join(' ') << " "; + t << fixLibFlags((*it).toKey()).join(' ') << ' '; } t << endl; @@ -3323,7 +3305,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt QString ret; if (project->isEmpty(replace_rule) || project->isActiveConfig("no_sed_meta_install")) { - ret += "-$(INSTALL_FILE) \"" + src + "\" \"" + dst + "\""; + ret += "-$(INSTALL_FILE) " + escapeFilePath(src) + ' ' + escapeFilePath(dst); } else { ret += "-$(SED)"; const ProStringList &replace_rules = project->values(replace_rule); @@ -3337,7 +3319,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt + "," + windowsifyPath(replace.toQString()) + ",gi"); } } - ret += " \"" + src + "\" >\"" + dst + "\""; + ret += ' ' + escapeFilePath(src) + " > " + escapeFilePath(dst); } return ret; } diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 672ba87683..7282d3ad1f 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -52,26 +52,12 @@ QT_BEGIN_NAMESPACE #define QT_PCLOSE pclose #endif -struct ReplaceExtraCompilerCacheKey -{ - mutable uint hash; - QString var, in, out, pwd; - ReplaceExtraCompilerCacheKey(const QString &v, const QStringList &i, const QStringList &o); - bool operator==(const ReplaceExtraCompilerCacheKey &f) const; - inline uint hashCode() const { - if(!hash) - hash = qHash(var) ^ qHash(in) ^ qHash(out) /*^ qHash(pwd)*/; - return hash; - } -}; -inline uint qHash(const ReplaceExtraCompilerCacheKey &f) { return f.hashCode(); } - struct ReplaceExtraCompilerCacheKey; class MakefileGenerator : protected QMakeSourceFileInfo { QString spec; - bool init_opath_already, init_already, no_io; + bool no_io; QHash<QString, bool> init_compiler_already; QString makedir, chkexists; QString build_args(const QString &outdir=QString()); @@ -81,6 +67,10 @@ class MakefileGenerator : protected QMakeSourceFileInfo mutable QHash<QString, QStringList> dependsCache; mutable QHash<ReplaceExtraCompilerCacheKey, QString> extraCompilerVariablesCache; +public: + // We can't make it visible to VCFilter in VS2008 except by making it public or directly friending it. + enum ReplaceFor { NoShell, LocalShell, TargetShell }; + protected: enum TARG_MODE { TARG_UNIX_MODE, TARG_MAC_MODE, TARG_WIN_MODE } target_mode; @@ -132,9 +122,9 @@ protected: //extra compiler interface bool verifyExtraCompiler(const ProString &c, const QString &f); - virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &); - inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out) - { return replaceExtraCompilerVariables(val, QStringList(in), QStringList(out)); } + virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor forShell); + inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out, ReplaceFor forShell) + { return replaceExtraCompilerVariables(val, QStringList(in), QStringList(out), forShell); } //interface to the source file info QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool); @@ -143,15 +133,12 @@ protected: QMakeProject *project; //escape - virtual QString unescapeFilePath(const QString &path) const; - ProString unescapeFilePath(const ProString &path) const; - virtual QStringList unescapeFilePaths(const QStringList &path) const; - ProStringList unescapeFilePaths(const ProStringList &path) const; virtual QString escapeFilePath(const QString &path) const { return path; } ProString escapeFilePath(const ProString &path) const; QStringList escapeFilePaths(const QStringList &paths) const; ProStringList escapeFilePaths(const ProStringList &paths) const; virtual QString escapeDependencyPath(const QString &path) const { return escapeFilePath(path); } + ProString escapeDependencyPath(const ProString &path) const; QStringList escapeDependencyPaths(const QStringList &paths) const; ProStringList escapeDependencyPaths(const ProStringList &paths) const; @@ -193,7 +180,6 @@ protected: //subclasses can use these to query information about how the generator was "run" QString buildArgs(); - QString fixifySpecdir(const QString &spec, const QString &outdir); virtual QStringList &findDependencies(const QString &file); virtual bool doDepends() const { return Option::mkfile::do_deps; } @@ -220,8 +206,12 @@ protected: //for retrieving values and lists of values virtual QString var(const ProKey &var) const; QString varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const; - QString fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const; QString varList(const ProKey &var) const; + QString fixFileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const; + QString fileVarList(const ProKey &var) const; + QString fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const; + QString fileVar(const ProKey &var) const; + QString depVar(const ProKey &var) const; QString val(const ProStringList &varList) const; QString val(const QStringList &varList) const; QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) const; @@ -231,6 +221,9 @@ protected: QString filePrefixRoot(const QString &, const QString &); + ProStringList fixLibFlags(const ProKey &var); + virtual ProString fixLibFlag(const ProString &lib); + //file fixification to unify all file names into a single pattern enum FileFixifyType { FileFixifyAbsolute, FileFixifyRelative, FileFixifyDefault }; QString fileFixify(const QString& file, const QString &out_dir=QString(), @@ -282,6 +275,21 @@ inline bool MakefileGenerator::findLibraries() inline MakefileGenerator::~MakefileGenerator() { } +struct ReplaceExtraCompilerCacheKey +{ + mutable uint hash; + QString var, in, out, pwd; + MakefileGenerator::ReplaceFor forShell; + ReplaceExtraCompilerCacheKey(const QString &v, const QStringList &i, const QStringList &o, MakefileGenerator::ReplaceFor s); + bool operator==(const ReplaceExtraCompilerCacheKey &f) const; + inline uint hashCode() const { + if (!hash) + hash = (uint)forShell ^ qHash(var) ^ qHash(in) ^ qHash(out) /*^ qHash(pwd)*/; + return hash; + } +}; +inline uint qHash(const ReplaceExtraCompilerCacheKey &f) { return f.hashCode(); } + QT_END_NAMESPACE #endif // MAKEFILE_H diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp index 4638d0b94e..79e017a560 100644 --- a/qmake/generators/makefiledeps.cpp +++ b/qmake/generators/makefiledeps.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -77,7 +77,7 @@ const QString &QMakeLocalFileName::local() const { if(!is_null && local_name.isNull()) - local_name = Option::fixPathToLocalOS(real_name, true); + local_name = Option::normalizePath(real_name); return local_name; } diff --git a/qmake/generators/makefiledeps.h b/qmake/generators/makefiledeps.h index 903b5b95e0..91fdaf0eee 100644 --- a/qmake/generators/makefiledeps.h +++ b/qmake/generators/makefiledeps.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 990bee6091..01e6fa4c6b 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -412,7 +412,6 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "msvc_nmake.h" #include "msvc_vcproj.h" #include "msvc_vcxproj.h" -#include "gbuild.h" QT_END_INCLUDE_NAMESPACE MakefileGenerator * @@ -452,8 +451,6 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new VcxprojGenerator; else mkfile = new NmakeMakefileGenerator; - } else if(gen == "GBUILD") { - mkfile = new GBuildMakefileGenerator; } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData()); } diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index 8ef3257ff7..1457a7aa7b 100644 --- a/qmake/generators/metamakefile.h +++ b/qmake/generators/metamakefile.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index cb00208a5b..bcda1dbf0c 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -55,17 +55,14 @@ QString project_builtin_regx() //calculate the builtin regular expression.. return ret; } -ProjectGenerator::ProjectGenerator() : MakefileGenerator(), init_flag(false) +ProjectGenerator::ProjectGenerator() : MakefileGenerator() { } void ProjectGenerator::init() { - if(init_flag) - return; int file_count = 0; - init_flag = true; verifyCompilers(); project->loadSpec(); @@ -311,7 +308,7 @@ ProjectGenerator::init() for (ProStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { ProStringList &inputs = project->values((*it2).toKey()); for (ProStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { - QString path = replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString()); + QString path = replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell); path = fixPathToQmake(path).section('/', -1); for(int i = 0; i < var_out.size(); ++i) { ProString v = var_out.at(i); @@ -491,7 +488,7 @@ ProjectGenerator::fixPathToQmake(const QString &file) { QString ret = file; if(Option::dir_sep != QLatin1String("/")) - ret = ret.replace(Option::dir_sep, QLatin1String("/")); + ret.replace(Option::dir_sep, QLatin1String("/")); return ret; } diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h index e1fe4ffca6..0744fa620e 100644 --- a/qmake/generators/projectgenerator.h +++ b/qmake/generators/projectgenerator.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -40,7 +40,6 @@ QT_BEGIN_NAMESPACE class ProjectGenerator : public MakefileGenerator { - bool init_flag; bool addFile(QString); bool addConfig(const QString &, bool add=true); QString getWritableVar(const char *, bool fixPath=true); diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index e54ddf8ad7..efea807209 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -45,10 +45,6 @@ QT_BEGIN_NAMESPACE void UnixMakefileGenerator::init() { - if(init_flag) - return; - init_flag = true; - if(project->isEmpty("QMAKE_EXTENSION_SHLIB")) { if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) { project->values("QMAKE_EXTENSION_SHLIB").append("so"); @@ -57,37 +53,14 @@ UnixMakefileGenerator::init() } } - if (project->isEmpty("QMAKE_PREFIX_SHLIB")) - // Prevent crash when using the empty variable. - project->values("QMAKE_PREFIX_SHLIB").append(""); - - if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */ - return; - ProStringList &configs = project->values("CONFIG"); if(project->isEmpty("ICON") && !project->isEmpty("RC_FILE")) project->values("ICON") = project->values("RC_FILE"); if(project->isEmpty("QMAKE_EXTENSION_PLUGIN")) project->values("QMAKE_EXTENSION_PLUGIN").append(project->first("QMAKE_EXTENSION_SHLIB")); - if(project->isEmpty("QMAKE_COPY_FILE")) - project->values("QMAKE_COPY_FILE").append("$(COPY)"); - if(project->isEmpty("QMAKE_STREAM_EDITOR")) - project->values("QMAKE_STREAM_EDITOR").append("sed"); - if(project->isEmpty("QMAKE_COPY_DIR")) - project->values("QMAKE_COPY_DIR").append("$(COPY) -R"); - if(project->isEmpty("QMAKE_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); if(project->isEmpty("QMAKE_LIBTOOL")) project->values("QMAKE_LIBTOOL").append("libtool --silent"); - if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) - project->values("QMAKE_SYMBOLIC_LINK").append("ln -f -s"); - if (!project->isEmpty("TARGET")) - project->values("TARGET") = escapeFilePaths(project->values("TARGET")); project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); //version handling @@ -122,8 +95,8 @@ UnixMakefileGenerator::init() } project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR"); - project->values("QMAKE_LIBS") += escapeFilePaths(project->values("LIBS")); - project->values("QMAKE_LIBS_PRIVATE") += escapeFilePaths(project->values("LIBS_PRIVATE")); + project->values("QMAKE_LIBS") += project->values("LIBS"); + project->values("QMAKE_LIBS_PRIVATE") += project->values("LIBS_PRIVATE"); if((!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib")) || (project->isActiveConfig("qt") && project->isActiveConfig("plugin"))) { if(configs.indexOf("dll") == -1) configs.append("dll"); @@ -205,13 +178,13 @@ UnixMakefileGenerator::init() pchBaseName += project->first("QMAKE_ORIG_TARGET").toQString(); // replace place holders - pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}", - project->first("PRECOMPILED_HEADER").toQString()); - pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName); + pchFlags.replace("${QMAKE_PCH_INPUT}", + escapeFilePath(project->first("PRECOMPILED_HEADER").toQString())); + pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", escapeFilePath(pchBaseName)); if (project->isActiveConfig("icc_pch_style")) { // icc style - pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT}", - pchBaseName + project->first("QMAKE_PCH_OUTPUT_EXT")); + pchFlags.replace("${QMAKE_PCH_OUTPUT}", + escapeFilePath(pchBaseName + project->first("QMAKE_PCH_OUTPUT_EXT"))); } else { // gcc style (including clang_pch_style) QString headerSuffix; @@ -235,8 +208,8 @@ UnixMakefileGenerator::init() } if(!pchOutputFile.isEmpty()) { - pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT}", - pchBaseName + pchOutputFile + headerSuffix); + pchFlags.replace("${QMAKE_PCH_OUTPUT}", + escapeFilePath(pchBaseName + pchOutputFile + headerSuffix)); } } @@ -267,15 +240,15 @@ UnixMakefileGenerator::init() ((project->isActiveConfig("build_pass") || project->isEmpty("BUILDS")))) { ProString bundle; if(project->isActiveConfig("bundle") && !project->isEmpty("QMAKE_BUNDLE_EXTENSION")) { - bundle = unescapeFilePath(project->first("TARGET")); + bundle = project->first("TARGET"); if(!project->isEmpty("QMAKE_BUNDLE_NAME")) - bundle = unescapeFilePath(project->first("QMAKE_BUNDLE_NAME")); + bundle = project->first("QMAKE_BUNDLE_NAME"); if(!bundle.endsWith(project->first("QMAKE_BUNDLE_EXTENSION"))) bundle += project->first("QMAKE_BUNDLE_EXTENSION"); } else if(project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) { - bundle = unescapeFilePath(project->first("TARGET")); + bundle = project->first("TARGET"); if(!project->isEmpty("QMAKE_APPLICATION_BUNDLE_NAME")) - bundle = unescapeFilePath(project->first("QMAKE_APPLICATION_BUNDLE_NAME")); + bundle = project->first("QMAKE_APPLICATION_BUNDLE_NAME"); if(!bundle.endsWith(".app")) bundle += ".app"; if(project->isEmpty("QMAKE_BUNDLE_LOCATION")) @@ -285,23 +258,23 @@ UnixMakefileGenerator::init() } else if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && ((!project->isActiveConfig("plugin") && project->isActiveConfig("lib_bundle")) || (project->isActiveConfig("plugin") && project->isActiveConfig("plugin_bundle")))) { - bundle = unescapeFilePath(project->first("TARGET")); + bundle = project->first("TARGET"); if(project->isActiveConfig("plugin")) { if(!project->isEmpty("QMAKE_PLUGIN_BUNDLE_NAME")) - bundle = unescapeFilePath(project->first("QMAKE_PLUGIN_BUNDLE_NAME")); - if(!project->isEmpty("QMAKE_BUNDLE_EXTENSION") && !bundle.endsWith(project->first("QMAKE_BUNDLE_EXTENSION"))) + bundle = project->first("QMAKE_PLUGIN_BUNDLE_NAME"); + if (project->isEmpty("QMAKE_BUNDLE_EXTENSION")) + project->values("QMAKE_BUNDLE_EXTENSION").append(".plugin"); + if (!bundle.endsWith(project->first("QMAKE_BUNDLE_EXTENSION"))) bundle += project->first("QMAKE_BUNDLE_EXTENSION"); - else if(!bundle.endsWith(".plugin")) - bundle += ".plugin"; if(project->isEmpty("QMAKE_BUNDLE_LOCATION")) project->values("QMAKE_BUNDLE_LOCATION").append("Contents/MacOS"); } else { if(!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME")) - bundle = unescapeFilePath(project->first("QMAKE_FRAMEWORK_BUNDLE_NAME")); - if(!project->isEmpty("QMAKE_BUNDLE_EXTENSION") && !bundle.endsWith(project->first("QMAKE_BUNDLE_EXTENSION"))) + bundle = project->first("QMAKE_FRAMEWORK_BUNDLE_NAME"); + if (project->isEmpty("QMAKE_BUNDLE_EXTENSION")) + project->values("QMAKE_BUNDLE_EXTENSION").append(".framework"); + if (!bundle.endsWith(project->first("QMAKE_BUNDLE_EXTENSION"))) bundle += project->first("QMAKE_BUNDLE_EXTENSION"); - else if(!bundle.endsWith(".framework")) - bundle += ".framework"; } } if(!bundle.isEmpty()) { @@ -368,7 +341,7 @@ UnixMakefileGenerator::init() if(QDir::isRelativePath(rpath)) rpath.prepend(Option::output_dir + Option::dir_sep); } - comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, false); + comp_flags += " -rpath " + escapeFilePath(Option::fixPathToTargetOS(rpath, false)); } } } @@ -389,10 +362,7 @@ QStringList &UnixMakefileGenerator::findDependencies(const QString &file) { QStringList &ret = MakefileGenerator::findDependencies(file); - // Note: The QMAKE_IMAGE_COLLECTION file have all images - // as dependency, so don't add precompiled header then - if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") - && file != project->first("QMAKE_IMAGE_COLLECTION")) { + if (doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { QString header_prefix; if(!project->isEmpty("PRECOMPILED_DIR")) header_prefix = project->first("PRECOMPILED_DIR").toQString(); @@ -456,6 +426,12 @@ QStringList return ret; } +ProString +UnixMakefileGenerator::fixLibFlag(const ProString &lib) +{ + return escapeFilePath(lib); +} + bool UnixMakefileGenerator::findLibraries() { @@ -482,7 +458,7 @@ UnixMakefileGenerator::findLibraries() } libdirs.insert(libidx++, f); if (!libArg.isEmpty()) - *it = libArg + lib; + *it = libArg + f.real(); } else if(opt.startsWith("-l")) { if (project->isActiveConfig("rvct_linker") || project->isActiveConfig("armcc_linker")) { (*it) = "lib" + opt.mid(2) + ".so"; @@ -517,12 +493,12 @@ UnixMakefileGenerator::findLibraries() if(!extn.isNull()) extens << extn; else - extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a"; + extens << project->first("QMAKE_EXTENSION_SHLIB") << "a"; for (ProStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { - QString pathToLib = ((*dep_it).local() + Option::dir_sep - + project->values("QMAKE_PREFIX_SHLIB").first() + QString pathToLib = ((*dep_it).local() + '/' + + project->first("QMAKE_PREFIX_SHLIB") + stub + "." + (*extit)); if(exists(pathToLib)) { (*it) = "-l" + stub; @@ -531,7 +507,7 @@ UnixMakefileGenerator::findLibraries() } } } else { - QString lib = dir + project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit); + QString lib = dir + project->first("QMAKE_PREFIX_SHLIB") + stub + "." + (*extit); if (exists(lib)) { (*it) = lib; found = true; @@ -541,8 +517,8 @@ UnixMakefileGenerator::findLibraries() } if(!found && project->isActiveConfig("compile_libtool")) { for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { - if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) { - (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext; + if (exists(libdirs[dep_i].local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + stub + Option::libtool_ext)) { + (*it) = libdirs[dep_i].real() + Option::dir_sep + project->first("QMAKE_PREFIX_SHLIB") + stub + Option::libtool_ext; found = true; break; } @@ -589,15 +565,15 @@ UnixMakefileGenerator::processPrlFiles() for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { const QMakeLocalFileName &lfn = libdirs[dep_i]; if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. - QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext; - if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) { + QString la = lfn.local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + lib + Option::libtool_ext; + if (exists(la) && QFile::exists(lfn.local() + "/.libs")) { QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; l.append("-L" + dot_libs); libdirs.insert(libidx++, QMakeLocalFileName(dot_libs)); } } - QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + prl_ext; + QString prl = lfn.local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + lib + prl_ext; if(processPrlFile(prl)) { if(prl.startsWith(lfn.local())) prl.replace(0, lfn.local().length(), lfn.real()); @@ -636,7 +612,7 @@ UnixMakefileGenerator::processPrlFiles() ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); if(!prl_libs.isEmpty()) { for(int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(lit+prl+1, escapeFilePath(prl_libs.at(prl).toQString())); + l.insert(lit+prl+1, prl_libs.at(prl).toQString()); prl_libs.clear(); } } @@ -726,10 +702,9 @@ UnixMakefileGenerator::defaultInstall(const QString &t) const QString root = "$(INSTALL_ROOT)"; ProStringList &uninst = project->values(ProKey(t + ".uninstall")); QString ret, destdir = project->first("DESTDIR").toQString(); - QString targetdir = Option::fixPathToTargetOS(project->first("target.path").toQString(), false); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; - targetdir = fileFixify(targetdir, FileFixifyAbsolute); + QString targetdir = fileFixify(project->first("target.path").toQString(), FileFixifyAbsolute); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; @@ -756,30 +731,31 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } for(int i = 0; i < targets.size(); ++i) { QString src = targets.at(i).toQString(), - dst = filePrefixRoot(root, targetdir + src.section('/', -1)); + dst = escapeFilePath(filePrefixRoot(root, targetdir + src.section('/', -1))); if(!ret.isEmpty()) ret += "\n\t"; - ret += "-$(INSTALL_FILE) \"" + src + "\" \"" + dst + "\""; + ret += "-$(INSTALL_FILE) " + escapeFilePath(src) + ' ' + dst; if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst + "\""); + uninst.append("-$(DEL_FILE) " + dst); } if (bundle == NoBundle && project->isActiveConfig("compile_libtool")) { - QString src_targ = target; + QString src_targ = escapeFilePath(target); if(src_targ == "$(TARGET)") src_targ = "$(TARGETL)"; QString dst_dir = fileFixify(targetdir, FileFixifyAbsolute); if(QDir::isRelativePath(dst_dir)) dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir); - ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + filePrefixRoot(root, dst_dir) + "\""; - uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\""); + ret = "-$(LIBTOOL) --mode=install cp " + src_targ + ' ' + escapeFilePath(filePrefixRoot(root, dst_dir)); + uninst.append("-$(LIBTOOL) --mode=uninstall " + src_targ); } else { QString src_targ = target; if(!destdir.isEmpty()) src_targ = Option::fixPathToTargetOS(destdir + target, false); QString plain_targ = filePrefixRoot(root, fileFixify(targetdir + target, FileFixifyAbsolute)); QString dst_targ = plain_targ; + plain_targ = escapeFilePath(plain_targ); if (bundle != NoBundle) { QString suffix; if (project->first("TEMPLATE") == "lib") @@ -790,33 +766,34 @@ UnixMakefileGenerator::defaultInstall(const QString &t) if (bundle == SolidBundle) { if (!ret.isEmpty()) ret += "\n\t"; - ret += "$(DEL_FILE) -r \"" + plain_targ + "\"\n\t"; + ret += "$(DEL_FILE) -r " + plain_targ + "\n\t"; } else { src_targ += suffix; } } + src_targ = escapeFilePath(src_targ); + dst_targ = escapeFilePath(dst_targ); if(!ret.isEmpty()) ret += "\n\t"; QString copy_cmd("-"); if (bundle == SolidBundle) { - copy_cmd += "$(INSTALL_DIR) \"" + src_targ + "\" \"" + plain_targ + "\""; + copy_cmd += "$(INSTALL_DIR) " + src_targ + ' ' + plain_targ; } else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { - copy_cmd += "$(INSTALL_FILE) \"" + src_targ + "\" \"" + dst_targ + "\""; + copy_cmd += "$(INSTALL_FILE) " + src_targ + ' ' + dst_targ; } else { if (bundle == SlicedBundle) - ret += mkdir_p_asstring("\"`dirname \"" + dst_targ + "\"`\"", false) + "\n\t"; - copy_cmd += "$(INSTALL_PROGRAM) \"" + src_targ + "\" \"" + dst_targ + "\""; + ret += mkdir_p_asstring("\"`dirname " + dst_targ + "`\"", false) + "\n\t"; + copy_cmd += "$(INSTALL_PROGRAM) " + src_targ + ' ' + dst_targ; } if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && project->values(ProKey(t + ".CONFIG")).indexOf("fix_rpath") != -1) { if(!project->isEmpty("QMAKE_FIX_RPATH")) { ret += copy_cmd; - ret += "\n\t-" + var("QMAKE_FIX_RPATH") + " \"" + - dst_targ + "\" \"" + dst_targ + "\""; + ret += "\n\t-" + var("QMAKE_FIX_RPATH") + ' ' + dst_targ + ' ' + dst_targ; } else if(!project->isEmpty("QMAKE_LFLAGS_RPATH")) { - ret += "-$(LINK) $(LFLAGS) " + var("QMAKE_LFLAGS_RPATH") + targetdir + " -o \"" + - dst_targ + "\" $(OBJECTS) $(LIBS) $(OBJCOMP)"; + ret += "-$(LINK) $(LFLAGS) " + var("QMAKE_LFLAGS_RPATH") + targetdir + " -o " + + dst_targ + " $(OBJECTS) $(LIBS) $(OBJCOMP)"; } else { ret += copy_cmd; } @@ -826,7 +803,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { if(!project->isEmpty("QMAKE_RANLIB")) - ret += QString("\n\t$(RANLIB) \"") + dst_targ + "\""; + ret += QString("\n\t$(RANLIB) ") + dst_targ; } else if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && !project->isEmpty("QMAKE_STRIP")) { ret += "\n\t-$(STRIP)"; @@ -837,27 +814,28 @@ UnixMakefileGenerator::defaultInstall(const QString &t) if (!project->isEmpty("QMAKE_STRIPFLAGS_APP")) ret += " " + var("QMAKE_STRIPFLAGS_APP"); } - ret += " \"" + dst_targ + "\""; + ret += ' ' + dst_targ; } if(!uninst.isEmpty()) uninst.append("\n\t"); if (bundle == SolidBundle) - uninst.append("-$(DEL_FILE) -r \"" + plain_targ + "\""); + uninst.append("-$(DEL_FILE) -r " + plain_targ); else - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + uninst.append("-$(DEL_FILE) " + dst_targ); if (bundle == SlicedBundle) { int dstlen = project->first("DESTDIR").length(); foreach (const ProString &src, project->values("QMAKE_BUNDLED_FILES")) { - QString file = unescapeFilePath(src.toQString()).mid(dstlen); - QString dst = filePrefixRoot(root, fileFixify(targetdir + file, FileFixifyAbsolute)); + ProString file = src.mid(dstlen); + QString dst = escapeFilePath( + filePrefixRoot(root, fileFixify(targetdir + file, FileFixifyAbsolute))); if (!ret.isEmpty()) ret += "\n\t"; - ret += mkdir_p_asstring("\"`dirname \"" + dst + "\"`\"", false) + "\n\t"; - ret += "-$(DEL_FILE) \"" + dst + "\"\n\t"; // Can't overwrite symlinks to directories - ret += "-$(INSTALL_DIR) " + src + " \"" + dst + "\""; // Use cp -R to copy symlinks + ret += mkdir_p_asstring("\"`dirname " + dst + "`\"", false) + "\n\t"; + ret += "-$(DEL_FILE) " + dst + "\n\t"; // Can't overwrite symlinks to directories + ret += "-$(INSTALL_DIR) " + escapeFilePath(src) + " " + dst; // Use cp -R to copy symlinks if (!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst + "\""); + uninst.append("-$(DEL_FILE) " + dst); } } if(!links.isEmpty()) { @@ -867,11 +845,12 @@ UnixMakefileGenerator::defaultInstall(const QString &t) int lslash = link.lastIndexOf(Option::dir_sep); if(lslash != -1) link = link.right(link.length() - (lslash + 1)); - QString dst_link = filePrefixRoot(root, fileFixify(targetdir + link, FileFixifyAbsolute)); - ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; + QString dst_link = escapeFilePath( + filePrefixRoot(root, fileFixify(targetdir + link, FileFixifyAbsolute))); + ret += "\n\t-$(SYMLINK) $(TARGET) " + dst_link; if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); + uninst.append("-$(DEL_FILE) " + dst_link); } } } @@ -896,7 +875,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) QString dst_meta = filePrefixRoot(root, fileFixify(targetdir + meta, FileFixifyAbsolute)); if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_meta + "\""); + uninst.append("-$(DEL_FILE) " + escapeFilePath(dst_meta)); const QString dst_meta_dir = fileInfo(dst_meta).path(); if(!dst_meta_dir.isEmpty()) { if(!ret.isEmpty()) @@ -917,8 +896,8 @@ UnixMakefileGenerator::escapeFilePath(const QString &path) const { QString ret = path; if(!ret.isEmpty()) { - ret = unescapeFilePath(ret).replace(QLatin1Char(' '), QLatin1String("\\ ")) - .replace(QLatin1Char('\t'), QLatin1String("\\\t")); + ret.replace(QLatin1Char(' '), QLatin1String("\\ ")) + .replace(QLatin1Char('\t'), QLatin1String("\\\t")); debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } return ret; diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index e90933649a..b136ea04d0 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE class UnixMakefileGenerator : public MakefileGenerator { - bool init_flag, include_deps; + bool include_deps; QString libtoolFileName(bool fixify=true); void writeLibtoolFile(); // for libtool void writePrlFile(QTextStream &); @@ -53,6 +53,7 @@ protected: virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); } virtual bool doDepends() const { return !Option::mkfile::do_stub_makefile && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); + virtual ProString fixLibFlag(const ProString &lib); virtual void processPrlFiles(); virtual bool findLibraries(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index f3a24a8681..7822107a37 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -38,13 +38,12 @@ #include <qbytearray.h> #include <qfile.h> #include <qdir.h> -#include <qdatetime.h> #include <qdebug.h> #include <time.h> QT_BEGIN_NAMESPACE -UnixMakefileGenerator::UnixMakefileGenerator() : MakefileGenerator(), init_flag(false), include_deps(false) +UnixMakefileGenerator::UnixMakefileGenerator() : MakefileGenerator(), include_deps(false) { } @@ -75,14 +74,14 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) if (writeDummyMakefile(t)) return true; - if (project->values("TEMPLATE").first() == "app" || - project->values("TEMPLATE").first() == "lib" || - project->values("TEMPLATE").first() == "aux") { + if (project->first("TEMPLATE") == "app" || + project->first("TEMPLATE") == "lib" || + project->first("TEMPLATE") == "aux") { if(Option::mkfile::do_stub_makefile && MakefileGenerator::writeStubMakefile(t)) return true; writeMakeParts(t); return MakefileGenerator::writeMakefile(t); - } else if(project->values("TEMPLATE").first() == "subdirs") { + } else if (project->first("TEMPLATE") == "subdirs") { MakefileGenerator::writeSubDirs(t); return true; } @@ -102,7 +101,7 @@ UnixMakefileGenerator::writeDefaultVariables(QTextStream &t) distname += project->first("VERSION"); project->values("QMAKE_DISTNAME") = distname; } - t << "DISTNAME = " << var("QMAKE_DISTNAME") << endl; + t << "DISTNAME = " << fileVar("QMAKE_DISTNAME") << endl; if (project->isEmpty("QMAKE_DISTDIR")) project->values("QMAKE_DISTDIR") = project->first("QMAKE_DISTNAME"); @@ -128,7 +127,7 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: } t << " FORCE\n\t" << mkdir_p_asstring("$(DISTDIR)", false) << "\n\t" - << "$(COPY_FILE) --parents " << var("DISTFILES") << " $(DISTDIR)" << Option::dir_sep << endl << endl; + << "$(COPY_FILE) --parents " << fileVar("DISTFILES") << " $(DISTDIR)" << Option::dir_sep << endl << endl; const QString abs_source_path = project->first("QMAKE_ABSOLUTE_SOURCE_PATH").toQString(); for (int target = 0; target < targets.size(); ++target) { @@ -149,8 +148,9 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: dist_directory.prepend(Option::dir_sep); QString out_directory_cdin = out_directory.isEmpty() ? "\n\t" - : "\n\tcd " + out_directory + " && "; - QString makefilein = " -e -f " + subtarget->makefile + " distdir DISTDIR=$(DISTDIR)" + dist_directory; + : "\n\tcd " + escapeFilePath(out_directory) + " && "; + QString makefilein = " -e -f " + escapeFilePath(subtarget->makefile) + + " distdir DISTDIR=$(DISTDIR)" + escapeFilePath(dist_directory); QString out = subtarget->makefile; QString in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); @@ -158,7 +158,7 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: out.remove(0, in_directory.length()); t << subtarget->target << "-distdir: FORCE"; - writeSubTargetCall(t, in_directory, in, out_directory, out, + writeSubTargetCall(t, in_directory, in, out_directory, escapeFilePath(out), out_directory_cdin, makefilein); t << endl; } @@ -167,7 +167,6 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { - QString deps = fileFixify(Option::output.fileName()), target_deps, prl; bool do_incremental = (project->isActiveConfig("incremental") && !project->values("QMAKE_INCREMENTAL").isEmpty() && (!project->values("QMAKE_APP_FLAG").isEmpty() || @@ -189,14 +188,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString isystem = var("QMAKE_CFLAGS_ISYSTEM"); const ProStringList &incs = project->values("INCLUDEPATH"); for(int i = 0; i < incs.size(); ++i) { - ProString inc = escapeFilePath(incs.at(i)); + const ProString &inc = incs.at(i); if (inc.isEmpty()) continue; if (!isystem.isEmpty() && isSystemInclude(inc.toQString())) - t << ' ' << isystem << ' ' << inc; + t << ' ' << isystem << ' '; else - t << " -I" << inc; + t << " -I"; + t << escapeFilePath(inc); } } if(!project->isEmpty("QMAKE_FRAMEWORKPATH_FLAGS")) @@ -208,7 +208,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { t << "LINK = " << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; - t << "LIBS = $(SUBLIBS) " << var("QMAKE_LIBS") << " " << var("QMAKE_LIBS_PRIVATE") << endl; + t << "LIBS = $(SUBLIBS) " << fixLibFlags("QMAKE_LIBS").join(' ') << ' ' + << fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl; } t << "AR = " << var("QMAKE_AR") << endl; @@ -221,16 +222,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << endl; t << "####### Output directory\n\n"; + // This is used in commands by some .prf files. if (! project->values("OBJECTS_DIR").isEmpty()) - t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl; + t << "OBJECTS_DIR = " << fileVar("OBJECTS_DIR") << endl; else t << "OBJECTS_DIR = ./\n"; t << endl; /* files */ t << "####### Files\n\n"; - t << "SOURCES = " << valList(escapeFilePaths(project->values("SOURCES"))) << " " - << valList(escapeFilePaths(project->values("GENERATED_SOURCES"))) << endl; + // This is used by the dist target. + t << "SOURCES = " << fileVarList("SOURCES") << ' ' << fileVarList("GENERATED_SOURCES") << endl; if(do_incremental) { const ProStringList &objs = project->values("OBJECTS"); const ProStringList &incrs = project->values("QMAKE_INCREMENTAL"); @@ -259,37 +261,37 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "INCREMENTAL_OBJECTS = " << escapeFilePaths(incrs_out).join(" \\\n\t\t") << endl; } } else { - t << "OBJECTS = " << valList(escapeFilePaths(project->values("OBJECTS"))) << endl; + // Used all over the place in both deps and commands. + t << "OBJECTS = " << valList(escapeDependencyPaths(project->values("OBJECTS"))) << endl; } if(do_incremental && !src_incremental) do_incremental = false; t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " " - << valList(escapeFilePaths(project->values("HEADERS"))) << " " - << valList(escapeFilePaths(project->values("SOURCES"))) << endl; - t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; + << fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << endl; + t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl; // The comment is important for mingw32-make.exe on Windows as otherwise trailing slashes // would be interpreted as line continuation. The lack of spacing between the value and the // comment is also important as otherwise quoted use of "$(DESTDIR)" would include this // spacing. - t << "DESTDIR = " << var("DESTDIR") << "#avoid trailing-slash linebreak\n"; + t << "DESTDIR = " << fileVar("DESTDIR") << "#avoid trailing-slash linebreak\n"; if(project->isActiveConfig("compile_libtool")) - t << "TARGETL = " << var("TARGET_la") << endl; - t << "TARGET = " << escapeFilePath(var("TARGET")) << endl; + t << "TARGETL = " << fileVar("TARGET_la") << endl; + t << "TARGET = " << fileVar("TARGET") << endl; // ### mixed use! if(project->isActiveConfig("plugin")) { - t << "TARGETD = " << escapeFilePath(var("TARGET")) << endl; + t << "TARGETD = " << fileVar("TARGET") << endl; } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty()) { - t << "TARGETA = " << escapeFilePath(var("TARGETA")) << endl; + t << "TARGETA = " << fileVar("TARGETA") << endl; // ### mixed use! if(!project->isEmpty("QMAKE_BUNDLE")) { - t << "TARGETD = " << escapeFilePath(var("TARGET_x.y")) << endl; - t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + t << "TARGETD = " << fileVar("TARGET_x.y") << endl; + t << "TARGET0 = " << fileVar("TARGET_") << endl; } else if (!project->isActiveConfig("unversioned_libname")) { - t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + t << "TARGET0 = " << fileVar("TARGET_") << endl; if (project->isEmpty("QMAKE_HPUX_SHLIB")) { - t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; - t << "TARGET1 = " << escapeFilePath(var("TARGET_x")) << endl; - t << "TARGET2 = " << escapeFilePath(var("TARGET_x.y")) << endl; + t << "TARGETD = " << fileVar("TARGET_x.y.z") << endl; + t << "TARGET1 = " << fileVar("TARGET_x") << endl; + t << "TARGET2 = " << fileVar("TARGET_x.y") << endl; } else { - t << "TARGETD = " << escapeFilePath(var("TARGET_x")) << endl; + t << "TARGETD = " << fileVar("TARGET_x") << endl; } } } @@ -301,7 +303,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) const ProStringList &qeui = project->values("QMAKE_EXTRA_INCLUDES"); ProStringList::ConstIterator it; for(it = qeui.begin(); it != qeui.end(); ++it) - t << "include " << (*it) << endl; + t << "include " << escapeDependencyPath(*it) << endl; /* rules */ t << "first: all\n"; @@ -322,29 +324,30 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList objects = project->values("OBJECTS"); for (ProStringList::Iterator it = objects.begin(); it != objects.end(); ++it) { QString d_file = (*it).toQString().replace(QRegExp(Option::obj_ext + "$"), ".d"); - t << "-include " << d_file << endl; + t << "-include " << escapeDependencyPath(d_file) << endl; project->values("QMAKE_DISTCLEAN") << d_file; } } else { QString cmd=var("QMAKE_CFLAGS_DEPS") + " "; cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D",""); if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) - cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " "; - cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", ""); + cmd += " -I" + fileVar("QMAKE_ABSOLUTE_SOURCE_PATH") + ' '; + cmd += " $(INCPATH) " + fileVarGlue("DEPENDPATH", "-I", " -I", ""); ProString odir; if(!project->values("OBJECTS_DIR").isEmpty()) odir = project->first("OBJECTS_DIR"); + QString odird = escapeDependencyPath(odir.toQString()); QString pwd = escapeFilePath(fileFixify(qmake_getpwd())); t << "###### Dependencies\n\n"; - t << odir << ".deps/%.d: " << pwd << "/%.cpp\n\t"; + t << odird << ".deps/%.d: " << pwd << "/%.cpp\n\t"; if(project->isActiveConfig("echo_depend_creation")) t << "@echo Creating depend for $<\n\t"; t << mkdir_p_asstring("$(@D)", false) << "\n\t" << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n"; - t << odir << ".deps/%.d: " << pwd << "/%.c\n\t"; + t << odird << ".deps/%.d: " << pwd << "/%.c\n\t"; if(project->isActiveConfig("echo_depend_creation")) t << "@echo Creating depend for $<\n\t"; t << mkdir_p_asstring("$(@D)", false) << "\n\t" @@ -375,11 +378,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!d_file.isEmpty()) { d_file = odir + ".deps/" + fileFixify(d_file, pwd, Option::output_dir) + ".d"; + QString d_file_d = escapeDependencyPath(d_file); QStringList deps = findDependencies((*it).toQString()).filter(QRegExp( "((^|/)" + Option::h_moc_mod + "|" + Option::cpp_moc_ext + "$)")); if(!deps.isEmpty()) - t << d_file << ": " << deps.join(' ') << endl; - t << "-include " << d_file << endl; + t << d_file_d << ": " << escapeDependencyPaths(deps).join(' ') << endl; + t << "-include " << d_file_d << endl; project->values("QMAKE_DISTCLEAN") += d_file; } } @@ -396,10 +400,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "SUBLIBS = "; const ProStringList &l = project->values("SUBLIBS"); for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) - t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." - << project->first("QMAKE_EXTENSION_STATICLIB") << " "; + t << escapeFilePath(libdir + project->first("QMAKE_PREFIX_STATICLIB") + (*it) + '.' + + project->first("QMAKE_EXTENSION_STATICLIB")) << ' '; t << endl << endl; } + QString target_deps; if ((project->isActiveConfig("depend_prl") || project->isActiveConfig("fast_depend_prl")) && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) { const ProStringList &l = project->values("QMAKE_PRL_INTERNAL_FILES"); @@ -412,18 +417,20 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(slsh != -1) dir = (*it).left(slsh + 1); QString targ = dir + libinfo.first("QMAKE_PRL_TARGET"); - target_deps += " " + targ; - t << targ; + QString targ_d = escapeDependencyPath(targ); + target_deps += ' ' + targ_d; + t << targ_d; if (project->isActiveConfig("fast_depend_prl")) t << ":\n\t@echo \"Creating '"; else t << ": FORCE\n\t@echo \"Creating/updating '"; t << targ << "'\"\n\t" - << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";" + << "(cd " << escapeFilePath(libinfo.first("QMAKE_PRL_BUILD_DIR")) << ';' << "$(MAKE))\n"; } } } + QString deps = escapeDependencyPath(fileFixify(Option::output.fileName())); QString allDeps; if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") { QString destdir = project->first("DESTDIR").toQString(); @@ -444,19 +451,23 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString incr_deps, incr_objs; if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; + QString incr_target_dir_d = escapeDependencyPath(incr_target_dir); + QString incr_target_dir_f = escapeFilePath(incr_target_dir); //actual target - t << incr_target_dir << ": $(OBJECTS)\n\t" - << "ld -r -o "<< incr_target_dir << " $(OBJECTS)\n"; + t << incr_target_dir_d << ": $(OBJECTS)\n\t" + << "ld -r -o " << incr_target_dir_f << " $(OBJECTS)\n"; //communicated below - deps.prepend(incr_target_dir + " "); + deps.prepend(incr_target_dir_d + ' '); incr_deps = "$(INCREMENTAL_OBJECTS)"; if(!incr_objs.isEmpty()) incr_objs += " "; - incr_objs += incr_target_dir; + incr_objs += incr_target_dir_f; } else { //actual target QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + - project->values("QMAKE_EXTENSION_SHLIB").first(); + project->first("QMAKE_EXTENSION_SHLIB"); + QString incr_target_dir_d = escapeDependencyPath(incr_target_dir); + QString incr_target_dir_f = escapeFilePath(incr_target_dir); QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(project->isActiveConfig("debug")) incr_lflags += var("QMAKE_LFLAGS_DEBUG"); @@ -464,31 +475,31 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) incr_lflags += var("QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); - t << incr_target_dir << ": $(INCREMENTAL_OBJECTS)\n\t"; + t << incr_target_dir_d << ": $(INCREMENTAL_OBJECTS)\n\t"; if(!destdir.isEmpty()) t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t"; - t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir << + t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir_f << " $(INCREMENTAL_OBJECTS)\n"; //communicated below if(!destdir.isEmpty()) { if(!incr_objs.isEmpty()) incr_objs += " "; - incr_objs += "-L" + destdir; + incr_objs += "-L" + escapeFilePath(destdir); } else { if(!incr_objs.isEmpty()) incr_objs += " "; - incr_objs += "-L" + qmake_getpwd(); + incr_objs += "-L" + escapeFilePath(qmake_getpwd()); } if(!incr_objs.isEmpty()) incr_objs += " "; - incr_objs += " -l" + incr_target; - deps.prepend(incr_target_dir + " "); + incr_objs += " -l" + escapeFilePath(incr_target); + deps.prepend(incr_target_dir_d + ' '); incr_deps = "$(OBJECTS)"; } //real target - t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps - << " " << var("POST_TARGETDEPS") << "\n\t"; + t << var("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' ' << incr_deps << ' ' << target_deps + << ' ' << depVar("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) @@ -498,8 +509,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " - << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; + t << "$(TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " + << target_deps << ' ' << depVar("POST_TARGETDEPS") << "\n\t"; if (project->first("TEMPLATE") != "aux") { if (!destdir.isEmpty()) t << mkdir_p_asstring(destdir) << "\n\t"; @@ -513,16 +524,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } allDeps = " $(TARGET)"; } else if(!project->isActiveConfig("staticlib")) { - QString destdir = unescapeFilePath(project->first("DESTDIR").toQString()), incr_deps; + QString destdir_r = project->first("DESTDIR").toQString(), incr_deps; if(!project->isEmpty("QMAKE_BUNDLE")) { QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION").toQString(); if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/")) bundle_loc.prepend("/"); if(!bundle_loc.endsWith("/")) bundle_loc += "/"; - destdir += project->first("QMAKE_BUNDLE") + bundle_loc; + destdir_r += project->first("QMAKE_BUNDLE") + bundle_loc; } - destdir = escapeFilePath(destdir); + QString destdir_d = escapeDependencyPath(destdir_r); + QString destdir = escapeFilePath(destdir_r); if(do_incremental) { ProString s_ext = project->first("QMAKE_EXTENSION_SHLIB"); @@ -531,23 +543,26 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(incr_target.indexOf(Option::dir_sep) != -1) incr_target = incr_target.right(incr_target.length() - (incr_target.lastIndexOf(Option::dir_sep) + 1)); - incr_target = escapeFilePath(incr_target); if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { - QString incr_target_dir = escapeFilePath(var("OBJECTS_DIR") + incr_target + Option::obj_ext); + QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; + QString incr_target_dir_d = escapeDependencyPath(incr_target_dir); + QString incr_target_dir_f = escapeFilePath(incr_target_dir); //actual target const QString link_deps = "$(OBJECTS) "; - t << incr_target_dir << ": " << link_deps << "\n\t" - << "ld -r -o " << incr_target_dir << " " << link_deps << endl; + t << incr_target_dir_d << ": " << link_deps << "\n\t" + << "ld -r -o " << incr_target_dir_f << ' ' << link_deps << endl; //communicated below ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD"); cmd[0] = cmd.at(0).toQString().replace("$(OBJECTS) ", "$(INCREMENTAL_OBJECTS)"); //ick - cmd.append(incr_target_dir); - deps.prepend(incr_target_dir + " "); + cmd.append(incr_target_dir_f); + deps.prepend(incr_target_dir_d + ' '); incr_deps = "$(INCREMENTAL_OBJECTS)"; } else { //actual target - QString incr_target_dir = escapeFilePath(destdir + "lib" + incr_target + "." + s_ext); + QString incr_target_dir = destdir_r + "lib" + incr_target + '.' + s_ext; + QString incr_target_dir_d = escapeDependencyPath(incr_target_dir); + QString incr_target_dir_f = escapeFilePath(incr_target_dir); QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL")) incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " "; @@ -557,29 +572,29 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) incr_lflags += var("QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); - t << incr_target_dir << ": $(INCREMENTAL_OBJECTS)\n\t"; + t << incr_target_dir_d << ": $(INCREMENTAL_OBJECTS)\n\t"; if(!destdir.isEmpty()) t << mkdir_p_asstring(destdir, false) << "\n\t"; - t << "$(LINK) " << incr_lflags << " " << var("QMAKE_LINK_O_FLAG") << incr_target_dir << + t << "$(LINK) " << incr_lflags << ' ' << var("QMAKE_LINK_O_FLAG") << incr_target_dir_f << " $(INCREMENTAL_OBJECTS)\n"; //communicated below ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD"); if(!destdir.isEmpty()) cmd.append(" -L" + destdir); - cmd.append(" -l" + incr_target); - deps.prepend(incr_target_dir + " "); + cmd.append(" -l" + escapeFilePath(incr_target)); + deps.prepend(incr_target_dir_d + ' '); incr_deps = "$(OBJECTS)"; } //real target - t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") << " " - << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS"); + t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") << ' ' + << incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS"); } else { - t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") + t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps - << " " << var("POST_TARGETDEPS"); + << ' ' << depVar("POST_TARGETDEPS"); } - allDeps = ' ' + destdir + "$(TARGET)"; + allDeps = ' ' + destdir_d + "$(TARGET)"; if(!destdir.isEmpty()) t << "\n\t" << mkdir_p_asstring(destdir, false); if(!project->isEmpty("QMAKE_PRE_LINK")) @@ -599,8 +614,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else if(!project->isEmpty("QMAKE_BUNDLE")) { - QString currentLink = destdir + "Versions/Current"; - bundledFiles << currentLink << destdir + "$(TARGET)"; + QString currentLink = destdir_r + "Versions/Current"; + QString currentLink_f = escapeDependencyPath(currentLink); + bundledFiles << currentLink << destdir_r + "$(TARGET)"; t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(DESTDIR)$(TARGET0)\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t" @@ -609,9 +625,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGET0)`\"", false) << "\n\t" << varGlue("QMAKE_LN_SHLIB", "-", " ", " Versions/Current/$(TARGET) $(DESTDIR)$(TARGET0)") << "\n\t" - << "-$(DEL_FILE) " << currentLink << "\n\t" + << "-$(DEL_FILE) " << currentLink_f << "\n\t" << varGlue("QMAKE_LN_SHLIB","-"," ", " " + project->first("QMAKE_FRAMEWORK_VERSION") + - " " + currentLink) << "\n\t"; + ' ' + currentLink_f) << "\n\t"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; @@ -668,10 +684,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (! project->isActiveConfig("plugin")) { t << "staticlib: $(TARGETA)\n\n"; - t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)"; + t << "$(TARGETA): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)"; if(do_incremental) t << " $(INCREMENTAL_OBJECTS)"; - t << " " << var("POST_TARGETDEPS") << "\n\t" + t << ' ' << depVar("POST_TARGETDEPS") << "\n\t" << "-$(DEL_FILE) $(TARGETA) \n\t" << var("QMAKE_AR_CMD"); if(do_incremental) @@ -681,15 +697,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << endl << endl; } } else { - QString destdir = project->first("DESTDIR").toQString(); - allDeps = ' ' + destdir + "$(TARGET)" - + varGlue("QMAKE_AR_SUBLIBS", ' ' + destdir, ' ' + destdir, ""); - t << "staticlib: " << destdir << "$(TARGET)\n\n"; + QString destdir_r = project->first("DESTDIR").toQString(); + QString destdir_d = escapeDependencyPath(destdir_r); + QString destdir = escapeFilePath(destdir_r); + allDeps = ' ' + destdir_d + "$(TARGET)" + + varGlue("QMAKE_AR_SUBLIBS", ' ' + destdir_d, ' ' + destdir_d, ""); + t << "staticlib: " << destdir_d << "$(TARGET)\n\n"; if(project->isEmpty("QMAKE_AR_SUBLIBS")) { - t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") - << " $(OBJECTS) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t"; + t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") + << " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) - t << mkdir_p_asstring(destdir) << "\n\t"; + t << mkdir_p_asstring(destdir, false) << "\n\t"; t << "-$(DEL_FILE) $(TARGET)\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -710,26 +728,27 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); QString ar; + ProString lib = escapeFilePath(*libit); if((*libit) == "$(TARGET)") { - t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") - << " " << var("POST_TARGETDEPS") << valList(build) << "\n\t"; + t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") + << ' ' << depVar("POST_TARGETDEPS") << valList(escapeDependencyPaths(build)) << "\n\t"; ar = project->first("QMAKE_AR_CMD").toQString(); - ar = ar.replace("$(OBJECTS)", build.join(' ')); + ar.replace("$(OBJECTS)", escapeFilePaths(build).join(' ')); } else { - t << (*libit) << ": " << valList(build) << "\n\t"; - ar = "$(AR) " + (*libit) + " " + build.join(' '); + t << escapeDependencyPath(*libit) << ": " << valList(escapeDependencyPaths(build)) << "\n\t"; + ar = "$(AR) " + lib + ' ' + escapeFilePaths(build).join(' '); } if(!destdir.isEmpty()) - t << mkdir_p_asstring(destdir) << "\n\t"; - t << "-$(DEL_FILE) " << (*libit) << "\n\t" + t << mkdir_p_asstring(destdir, false) << "\n\t"; + t << "-$(DEL_FILE) " << lib << "\n\t" << ar << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) - t << "\t$(RANLIB) " << (*libit) << "\n"; + t << "\t$(RANLIB) " << lib << "\n"; if(!destdir.isEmpty()) - t << "\t-$(DEL_FILE) " << destdir << (*libit) << "\n" - << "\t-$(MOVE) " << (*libit) << " " << destdir << " \n"; + t << "\t-$(DEL_FILE) " << destdir << lib << "\n" + << "\t-$(MOVE) " << lib << ' ' << destdir << " \n"; } } t << endl << endl; @@ -747,7 +766,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } if(!meta_files.isEmpty()) t << escapeDependencyPaths(meta_files).join(" ") << ": \n\t" - << "@$(QMAKE) -prl " << buildArgs() << " " << project->projectFile() << endl; + << "@$(QMAKE) -prl " << buildArgs() << ' ' << escapeFilePath(project->projectFile()) << endl; } if (!project->isEmpty("QMAKE_BUNDLE")) { @@ -755,50 +774,54 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList &alldeps = project->values("ALL_DEPS"); QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/"; if (!project->first("QMAKE_PKGINFO").isEmpty()) { - ProString pkginfo = escapeFilePath(project->first("QMAKE_PKGINFO")); + ProString pkginfo = project->first("QMAKE_PKGINFO"); + ProString pkginfo_f = escapeFilePath(pkginfo); + ProString pkginfo_d = escapeDependencyPath(pkginfo); bundledFiles << pkginfo; alldeps << pkginfo; QString destdir = bundle_dir + "Contents"; - t << pkginfo << ": \n\t"; + t << pkginfo_d << ": \n\t"; if (!destdir.isEmpty()) t << mkdir_p_asstring(destdir) << "\n\t"; - t << "@$(DEL_FILE) " << pkginfo << "\n\t" + t << "@$(DEL_FILE) " << pkginfo_f << "\n\t" << "@echo \"APPL" << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) - << "\" >" << pkginfo << endl; + << "\" > " << pkginfo_f << endl; } if (!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) { - ProString resources = escapeFilePath(project->first("QMAKE_BUNDLE_RESOURCE_FILE")); + ProString resources = project->first("QMAKE_BUNDLE_RESOURCE_FILE"); + ProString resources_f = escapeFilePath(resources); + ProString resources_d = escapeDependencyPath(resources); bundledFiles << resources; alldeps << resources; QString destdir = bundle_dir + "Contents/Resources"; - t << resources << ": \n\t"; + t << resources_d << ": \n\t"; t << mkdir_p_asstring(destdir) << "\n\t"; - t << "@touch " << resources << "\n\t\n"; + t << "@touch " << resources_f << "\n\t\n"; } //copy the plist while (!project->isActiveConfig("no_plist")) { // 'while' just to be able to 'break' QString info_plist = project->first("QMAKE_INFO_PLIST").toQString(); if (info_plist.isEmpty()) { info_plist = escapeFilePath(specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE")); - } else if (!exists(Option::fixPathToLocalOS(info_plist))) { + } else if (!exists(Option::normalizePath(info_plist))) { warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", info_plist.toLatin1().constData()); break; } else { info_plist = escapeFilePath(fileFixify(info_plist)); } - bool isApp = (project->first("TEMPLATE") == "app"); - QString info_plist_out = escapeFilePath( + QString info_plist_out = bundle_dir + (isApp ? "Contents/Info.plist" : "Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") - + "/Resources/Info.plist")); + + "/Resources/Info.plist"); bundledFiles << info_plist_out; alldeps << info_plist_out; QString destdir = info_plist_out.section(Option::dir_sep, 0, -2); - t << info_plist_out << ": \n\t"; + t << escapeDependencyPath(info_plist_out) << ": \n\t"; + info_plist_out = escapeFilePath(info_plist_out); if (!destdir.isEmpty()) t << mkdir_p_asstring(destdir, false) << "\n\t"; ProStringList commonSedArgs; @@ -838,13 +861,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //copy the icon if (!project->isEmpty("ICON")) { QString dir = bundle_dir + "Contents/Resources/"; - const QString icon_path = escapeFilePath(dir + icon.section(Option::dir_sep, -1)); + const QString icon_path = dir + icon.section(Option::dir_sep, -1); + QString icon_path_f = escapeFilePath(icon_path); bundledFiles << icon_path; alldeps << icon_path; - t << icon_path << ": " << icon << "\n\t" + t << escapeDependencyPath(icon_path) << ": " << escapeDependencyPath(icon) << "\n\t" << mkdir_p_asstring(dir) << "\n\t" - << "@$(DEL_FILE) " << icon_path << "\n\t" - << "@$(COPY_FILE) " << escapeFilePath(icon) << " " << icon_path << endl; + << "@$(DEL_FILE) " << icon_path_f << "\n\t" + << "@$(COPY_FILE) " << escapeFilePath(icon) << ' ' << icon_path_f << endl; } } else { symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources"; @@ -875,23 +899,24 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) int pos = name.indexOf('/'); if (pos > 0) name = name.mid(0, pos); - symlinks[Option::fixPathToLocalOS(path + name)] = + symlinks[Option::fixPathToTargetOS(path + name)] = project->first(vkey) + "/Current/" + name; path += version; } path += project->first(pkey).toQString(); - path = Option::fixPathToLocalOS(path); + path = Option::fixPathToTargetOS(path); for(int file = 0; file < files.count(); file++) { QString fn = files.at(file).toQString(); QString src = fileFixify(fn, FileFixifyAbsolute); if (!QFile::exists(src)) src = fn; - src = escapeFilePath(src); - const QString dst = escapeFilePath(path + Option::dir_sep + fileInfo(fn).fileName()); + QString dst = path + Option::dir_sep + fileInfo(fn).fileName(); bundledFiles << dst; alldeps << dst; - t << dst << ": " << src << "\n\t" + t << escapeDependencyPath(dst) << ": " << escapeDependencyPath(src) << "\n\t" << mkdir_p_asstring(path) << "\n\t"; + src = escapeFilePath(src); + dst = escapeFilePath(dst); QFileInfo fi(fileInfo(fn)); if(fi.isDir()) t << "@$(DEL_FILE) -r " << dst << "\n\t" @@ -902,18 +927,19 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } } + QString bundle_dir_f = escapeFilePath(bundle_dir); QHash<QString, QString>::ConstIterator symIt = symlinks.constBegin(), symEnd = symlinks.constEnd(); for (; symIt != symEnd; ++symIt) { bundledFiles << symIt.key(); alldeps << symIt.key(); - t << symIt.key() << ":\n\t" + t << escapeDependencyPath(symIt.key()) << ":\n\t" << mkdir_p_asstring(bundle_dir) << "\n\t" - << "@$(SYMLINK) " << symIt.value() << " " << bundle_dir << endl; + << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; } } - t << endl << "all: " << escapeDependencyPath(deps) + t << endl << "all: " << deps << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")), " \\\n\t\t", " \\\n\t\t", "") << allDeps << endl << endl; @@ -934,15 +960,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) const ProStringList &val = project->values((*var_it).toKey()); if(val.isEmpty()) continue; - t << "\t$(COPY_FILE) --parents " << val.join(' ') << " $(DISTDIR)" << Option::dir_sep << endl; + t << "\t$(COPY_FILE) --parents " << escapeFilePaths(val).join(' ') + << " $(DISTDIR)" << Option::dir_sep << endl; } } } if(!project->isEmpty("TRANSLATIONS")) - t << "\t$(COPY_FILE) --parents " << var("TRANSLATIONS") << " $(DISTDIR)" << Option::dir_sep << endl; + t << "\t$(COPY_FILE) --parents " << fileVar("TRANSLATIONS") << " $(DISTDIR)" << Option::dir_sep << endl; t << endl << endl; - QString clean_targets = "compiler_clean " + var("CLEAN_DEPS"); + QString clean_targets = " compiler_clean " + depVar("CLEAN_DEPS"); if(do_incremental) { t << "incrclean:\n"; if(src_incremental) @@ -997,28 +1024,27 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) precomp_files += precomph_out_dir + header_prefix + "objective-c++" + header_suffix; } } - t << "-$(DEL_FILE) " << precomp_files.join(' ') << "\n\t"; + t << "-$(DEL_FILE) " << escapeFilePaths(precomp_files).join(' ') << "\n\t"; } - if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t"; if(src_incremental) t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)\n\t"; - t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t") + t << fileVarGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t") << "-$(DEL_FILE) *~ core *.core\n" - << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl; + << fileVarGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl; ProString destdir = project->first("DESTDIR"); if (!destdir.isEmpty() && !destdir.endsWith(Option::dir_sep)) destdir += Option::dir_sep; - t << "distclean: clean " << var("DISTCLEAN_DEPS") << '\n'; + t << "distclean: clean " << depVar("DISTCLEAN_DEPS") << '\n'; if(!project->isEmpty("QMAKE_BUNDLE")) { QString bundlePath = escapeFilePath(destdir + project->first("QMAKE_BUNDLE")); t << "\t-$(DEL_FILE) -r " << bundlePath << endl; } else if(project->isActiveConfig("compile_libtool")) { t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) $(TARGET)\n"; } else if (project->isActiveConfig("staticlib")) { - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; + t << "\t-$(DEL_FILE) " << escapeFilePath(destdir) << "$(TARGET) \n"; } else if (project->values("QMAKE_APP_FLAG").isEmpty() && !project->isActiveConfig("plugin")) { + destdir = escapeFilePath(destdir); t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; if (!project->isActiveConfig("unversioned_libname")) { t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " @@ -1029,11 +1055,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else { t << "\t-$(DEL_FILE) $(TARGET) \n"; } - t << varGlue("QMAKE_DISTCLEAN","\t-$(DEL_FILE) "," ","\n"); + t << fileVarGlue("QMAKE_DISTCLEAN","\t-$(DEL_FILE) "," ","\n"); { - QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); + QString ofile = fileFixify(Option::output.fileName()); if(!ofile.isEmpty()) - t << "\t-$(DEL_FILE) " << ofile << endl; + t << "\t-$(DEL_FILE) " << escapeFilePath(ofile) << endl; } t << endl << endl; @@ -1044,8 +1070,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) libdir = project->first("SUBLIBS_DIR"); const ProStringList &l = project->values("SUBLIBS"); for (it = l.begin(); it != l.end(); ++it) - t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." - << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t" + t << escapeDependencyPath(libdir + project->first("QMAKE_PREFIX_STATICLIB") + (*it) + '.' + + project->first("QMAKE_EXTENSION_STATICLIB")) << ":\n\t" << var(ProKey("MAKELIB" + *it)) << endl << endl; } @@ -1075,13 +1101,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (project->isActiveConfig("icc_pch_style")) { // icc style QString sourceFile = pchOutput + Option::cpp_ext.first(); + QString sourceFile_f = escapeFilePath(sourceFile); QString objectFile = createObjectList(ProStringList(sourceFile)).first().toQString(); - t << pchOutput << ": " << pchInput << " " << findDependencies(pchInput).join(" \\\n\t\t") - << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile - << "\n\trm -f " << pchOutput; + t << escapeDependencyPath(pchOutput) << ": " << escapeDependencyPath(pchInput) << ' ' + << escapeDependencyPaths(findDependencies(pchInput)).join(" \\\n\t\t") + << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile_f + << "\n\trm -f " << escapeFilePath(pchOutput); - pchFlags = pchFlags.replace("${QMAKE_PCH_TEMP_SOURCE}", sourceFile) - .replace("${QMAKE_PCH_TEMP_OBJECT}", objectFile); + pchFlags.replace("${QMAKE_PCH_TEMP_SOURCE}", sourceFile_f) + .replace("${QMAKE_PCH_TEMP_OBJECT}", escapeFilePath(objectFile)); } else { // gcc style (including clang_pch_style) ProString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); @@ -1104,12 +1132,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) continue; pchOutput += header_prefix + pchOutputFile + header_suffix; - t << pchOutput << ": " << pchInput << " " << findDependencies(pchInput).join(" \\\n\t\t") + t << escapeDependencyPath(pchOutput) << ": " << escapeDependencyPath(pchInput) << ' ' + << escapeDependencyPaths(findDependencies(pchInput)).join(" \\\n\t\t") << "\n\t" << mkdir_p_asstring(pchOutputDir); } - pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}", pchInput) - .replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName.toQString()) - .replace("${QMAKE_PCH_OUTPUT}", pchOutput.toQString()); + pchFlags.replace("${QMAKE_PCH_INPUT}", escapeFilePath(pchInput)) + .replace("${QMAKE_PCH_OUTPUT_BASE}", escapeFilePath(pchBaseName.toQString())) + .replace("${QMAKE_PCH_OUTPUT}", escapeFilePath(pchOutput.toQString())); QString compiler; if(comps[i] == "C" || comps[i] == "OBJC" || comps[i] == "OBJCXX") @@ -1129,9 +1158,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) void UnixMakefileGenerator::init2() { if(project->isEmpty("QMAKE_FRAMEWORK_VERSION")) - project->values("QMAKE_FRAMEWORK_VERSION").append(project->values("VER_MAJ").first()); + project->values("QMAKE_FRAMEWORK_VERSION").append(project->first("VER_MAJ")); - if (project->values("TEMPLATE").first() == "aux") + if (project->first("TEMPLATE") == "aux") return; if (!project->values("QMAKE_APP_FLAG").isEmpty()) { @@ -1172,11 +1201,11 @@ void UnixMakefileGenerator::init2() if(!bundle_loc.endsWith("/")) bundle_loc += "/"; project->values("TARGET_").append(project->first("QMAKE_BUNDLE") + - bundle_loc + unescapeFilePath(project->first("TARGET"))); + bundle_loc + project->first("TARGET")); project->values("TARGET_x.y").append(project->first("QMAKE_BUNDLE") + "/Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") + - bundle_loc + unescapeFilePath(project->first("TARGET"))); + bundle_loc + project->first("TARGET")); } else if(project->isActiveConfig("plugin")) { QString prefix; if(!project->isActiveConfig("no_plugin_name_prefix")) @@ -1248,7 +1277,7 @@ void UnixMakefileGenerator::init2() project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT") + "." + - project->values("QMAKE_EXTENSION_SHLIB").first()); + project->first("QMAKE_EXTENSION_SHLIB")); } else { project->values("TARGET_x").append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + @@ -1259,8 +1288,8 @@ void UnixMakefileGenerator::init2() "." + project->first("VER_MIN")); project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." + - project->values( - "QMAKE_EXTENSION_SHLIB").first() + "." + + project->first( + "QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT")); @@ -1270,8 +1299,6 @@ void UnixMakefileGenerator::init2() else project->values("TARGET") = project->values("TARGET_x.y.z"); } - if(project->isEmpty("QMAKE_LN_SHLIB")) - project->values("QMAKE_LN_SHLIB").append("ln -s"); if (!project->values("QMAKE_LFLAGS_SONAME").isEmpty()) { ProString soname; if(project->isActiveConfig("plugin")) { @@ -1369,7 +1396,7 @@ UnixMakefileGenerator::libtoolFileName(bool fixify) if(fixify) { if(QDir::isRelativePath(ret) && !project->isEmpty("DESTDIR")) ret.prepend(project->first("DESTDIR").toQString()); - ret = Option::fixPathToLocalOS(fileFixify(ret, qmake_getpwd(), Option::output_dir)); + ret = fileFixify(ret, qmake_getpwd(), Option::output_dir); } return ret; } @@ -1390,26 +1417,27 @@ UnixMakefileGenerator::writeLibtoolFile() QTextStream t(&ft); t << "# " << lname << " - a libtool library file\n"; t << "# Generated by qmake/libtool (" QMAKE_VERSION_STR ") (Qt " - << QT_VERSION_STR << ") on: " << QDateTime::currentDateTime().toString(); + << QT_VERSION_STR << ")"; t << "\n"; t << "# The name that we can dlopen(3).\n" - << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x") + << "dlname='" << fileVar(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x") << "'\n\n"; t << "# Names of this library.\n"; t << "library_names='"; if(project->isActiveConfig("plugin")) { - t << var("TARGET"); + t << fileVar("TARGET"); } else { if (project->isEmpty("QMAKE_HPUX_SHLIB")) - t << var("TARGET_x.y.z") << " "; - t << var("TARGET_x") << " " << var("TARGET_"); + t << fileVar("TARGET_x.y.z") << ' '; + t << fileVar("TARGET_x") << ' ' << fileVar("TARGET_"); } t << "'\n\n"; t << "# The name of the static archive.\n" - << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n"; + << "old_library='" << escapeFilePath(lname.left(lname.length()-Option::libtool_ext.length())) + << ".a'\n\n"; t << "# Libraries that this one depends upon.\n"; ProStringList libs; @@ -1419,7 +1447,7 @@ UnixMakefileGenerator::writeLibtoolFile() libs << "QMAKE_LIBS"; //obvious one t << "dependency_libs='"; for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) - t << project->values((*it).toKey()).join(' ') << " "; + t << fixLibFlags((*it).toKey()).join(' ') << ' '; t << "'\n\n"; t << "# Version information for " << lname << "\n"; diff --git a/qmake/generators/win32/cesdkhandler.cpp b/qmake/generators/win32/cesdkhandler.cpp index f2e6758704..3afed2b8c1 100644 --- a/qmake/generators/win32/cesdkhandler.cpp +++ b/qmake/generators/win32/cesdkhandler.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/win32/cesdkhandler.h b/qmake/generators/win32/cesdkhandler.h index d3894087b2..42c0121720 100644 --- a/qmake/generators/win32/cesdkhandler.h +++ b/qmake/generators/win32/cesdkhandler.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index f2d6678cdf..c19e17bc0e 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -44,19 +44,14 @@ QT_BEGIN_NAMESPACE -MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator(), init_flag(false) +MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator() { - if (isWindowsShell()) - quote = "\""; - else - quote = "'"; } QString MingwMakefileGenerator::escapeDependencyPath(const QString &path) const { QString ret = path; - ret.remove('\"'); - ret.replace('\\', "/"); + ret.replace('\\', "/"); // ### this shouldn't be here ret.replace(' ', "\\ "); return ret; } @@ -66,6 +61,18 @@ QString MingwMakefileGenerator::getLibTarget() return QString("lib" + project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".a"); } +QString MingwMakefileGenerator::getManifestFileForRcFile() const +{ + return project->first("QMAKE_MANIFEST").toQString(); +} + +ProString MingwMakefileGenerator::fixLibFlag(const ProString &lib) +{ + if (lib.startsWith("lib")) + return QStringLiteral("-l") + escapeFilePath(lib.mid(3)); + return escapeFilePath(lib); +} + bool MingwMakefileGenerator::findLibraries() { QList<QMakeLocalFileName> dirs; @@ -84,9 +91,9 @@ bool MingwMakefileGenerator::findLibraries() if (ver > 0) extension += QString::number(ver); extension += suffix; - if(QMakeMetaInfo::libExists((*dir_it).local() + Option::dir_sep + steam) || - exists((*dir_it).local() + Option::dir_sep + steam + extension + ".a") || - exists((*dir_it).local() + Option::dir_sep + steam + extension + ".dll.a")) { + if (QMakeMetaInfo::libExists((*dir_it).local() + '/' + steam) + || exists((*dir_it).local() + '/' + steam + extension + ".a") + || exists((*dir_it).local() + '/' + steam + extension + ".dll.a")) { out = *it + extension; break; } @@ -94,7 +101,9 @@ bool MingwMakefileGenerator::findLibraries() if (!out.isEmpty()) // We assume if it never finds it that its correct (*it) = out; } else if ((*it).startsWith("-L")) { - dirs.append(QMakeLocalFileName((*it).mid(2).toQString())); + QMakeLocalFileName f((*it).mid(2).toQString()); + dirs.append(f); + *it = "-L" + f.real(); } ++it; @@ -119,7 +128,7 @@ bool MingwMakefileGenerator::writeMakefile(QTextStream &t) t << "QMAKE = " << var("QMAKE_QMAKE") << endl; const ProStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); for (ProStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) - t << *it << " "; + t << escapeDependencyPath(*it) << ' '; t << "first all clean install distclean uninstall: qmake\n" << "qmake_all:\n"; writeMakeQmake(t); @@ -145,6 +154,7 @@ void createLdObjectScriptFile(const QString &fileName, const ProStringList &objL t << "INPUT(\n"; for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { QString path = (*it).toQString(); + // ### quoting? if (QDir::isRelativePath(path)) t << "./" << path << endl; else @@ -162,6 +172,7 @@ void createArObjectScriptFile(const QString &fileName, const QString &target, co QFile file(filePath); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream t(&file); + // ### quoting? t << "CREATE " << target << endl; for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { t << "ADDMOD " << *it << endl; @@ -180,6 +191,7 @@ void createRvctObjectScriptFile(const QString &fileName, const ProStringList &ob QTextStream t(&file); for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { QString path = (*it).toQString(); + // ### quoting? if (QDir::isRelativePath(path)) t << "./" << path << endl; else @@ -200,23 +212,19 @@ void MingwMakefileGenerator::writeMingwParts(QTextStream &t) t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " " << escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t") << "\n\t" << mkdir_p_asstring(preCompHeaderOut) - << "\n\t$(CC) -x c-header -c $(CFLAGS) $(INCPATH) -o " << cHeader << " " << header - << endl << endl; + << "\n\t$(CC) -x c-header -c $(CFLAGS) $(INCPATH) -o " << escapeFilePath(cHeader) + << ' ' << escapeFilePath(header) << endl << endl; QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++"; t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " " << escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t") << "\n\t" << mkdir_p_asstring(preCompHeaderOut) - << "\n\t$(CXX) -x c++-header -c $(CXXFLAGS) $(INCPATH) -o " << cppHeader << " " << header - << endl << endl; + << "\n\t$(CXX) -x c++-header -c $(CXXFLAGS) $(INCPATH) -o " << escapeFilePath(cppHeader) + << ' ' << escapeFilePath(header) << endl << endl; } } void MingwMakefileGenerator::init() { - if(init_flag) - return; - init_flag = true; - /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") project->values("QMAKE_APP_FLAG").append("1"); @@ -224,16 +232,6 @@ void MingwMakefileGenerator::init() project->values("QMAKE_LIB_FLAG").append("1"); else if(project->first("TEMPLATE") == "subdirs") { MakefileGenerator::init(); - if(project->isEmpty("QMAKE_COPY_FILE")) - 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_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); return; @@ -245,15 +243,7 @@ void MingwMakefileGenerator::init() processVars(); - if (!project->values("RES_FILE").isEmpty()) { - project->values("QMAKE_LIBS") += escapeFilePaths(project->values("RES_FILE")); - } - - ProStringList &configs = project->values("CONFIG"); - - if(project->isActiveConfig("qt_dll")) - if(configs.indexOf("qt") == -1) - configs.append("qt"); + project->values("QMAKE_LIBS") += project->values("RES_FILE"); if (project->isActiveConfig("dll")) { QString destDir = ""; @@ -261,7 +251,7 @@ void MingwMakefileGenerator::init() destDir = Option::fixPathToTargetOS(project->first("DESTDIR") + Option::dir_sep, false, false); project->values("MINGW_IMPORT_LIB").prepend(destDir + "lib" + project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".a"); - project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + project->first("MINGW_IMPORT_LIB")); + project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + fileVar("MINGW_IMPORT_LIB")); } if (!project->values("DEF_FILE").isEmpty()) { @@ -283,6 +273,7 @@ void MingwMakefileGenerator::init() project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c"); project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++"); + preCompHeader = escapeFilePath(preCompHeader); project->values("QMAKE_RUN_CC").clear(); project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader + " $(CFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$obj $src"); @@ -311,13 +302,12 @@ void MingwMakefileGenerator::writeIncPart(QTextStream &t) for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit).toQString(); inc.replace(QRegExp("\\\\$"), ""); - inc.replace(QRegExp("\""), ""); if (!isystem.isEmpty() && isSystemInclude(inc)) t << isystem << ' '; else t << "-I"; - t << quote << inc << quote << " "; + t << escapeFilePath(inc) << ' '; } t << endl; } @@ -330,8 +320,8 @@ void MingwMakefileGenerator::writeLibsPart(QTextStream &t) t << "LINKER = " << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; t << "LIBS = " - << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << ' ' - << var("QMAKE_LIBS_PRIVATE").replace(QRegExp("(\\slib|^lib)")," -l") << endl; + << fixLibFlags("QMAKE_LIBS").join(' ') << ' ' + << fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl; } } @@ -350,7 +340,7 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) QString ar_cmd = project->values("QMAKE_LIB").join(' '); if (ar_cmd.isEmpty()) ar_cmd = "armar --create"; - objectsLinkLine = ar_cmd + " " + var("DEST_TARGET") + " --via " + escapeFilePath(ar_script_file); + objectsLinkLine = ar_cmd + ' ' + fileVar("DEST_TARGET") + " --via " + escapeFilePath(ar_script_file); } else { // Strip off any options since the ar commands will be read from file. QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0);; @@ -378,8 +368,9 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) { t << "first: all\n"; - t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS"))," "," "," ") << " $(DESTDIR_TARGET)\n\n"; - t << "$(DESTDIR_TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS"); + t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) + << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n"; + t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <<var("QMAKE_PRE_LINK"); if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { @@ -414,8 +405,8 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) } if (!rc_file.isEmpty()) { - t << escapeDependencyPath(var("RES_FILE")) << ": " << rc_file << "\n\t" - << var("QMAKE_RC") << " -i " << rc_file << " -o " << var("RES_FILE") + t << escapeDependencyPath(var("RES_FILE")) << ": " << escapeDependencyPath(rc_file) << "\n\t" + << var("QMAKE_RC") << " -i " << escapeFilePath(rc_file) << " -o " << fileVar("RES_FILE") << incPathStr << " $(DEFINES)\n\n"; } } @@ -423,10 +414,7 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) QStringList &MingwMakefileGenerator::findDependencies(const QString &file) { QStringList &aList = MakefileGenerator::findDependencies(file); - // Note: The QMAKE_IMAGE_COLLECTION file have all images - // as dependency, so don't add precompiled header then - if (file == project->first("QMAKE_IMAGE_COLLECTION") - || preCompHeaderOut.isEmpty()) + if (preCompHeaderOut.isEmpty()) return aList; for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { if (file.endsWith(*it)) { diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index 2442ea852b..e76391080c 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -45,7 +45,10 @@ public: ~MingwMakefileGenerator(); protected: QString escapeDependencyPath(const QString &path) const; + ProString escapeDependencyPath(const ProString &path) const { return MakefileGenerator::escapeDependencyPath(path); } + virtual ProString fixLibFlag(const ProString &lib); QString getLibTarget(); + virtual QString getManifestFileForRcFile() const; bool writeMakefile(QTextStream &); void init(); private: @@ -62,9 +65,7 @@ private: virtual bool findLibraries(); - bool init_flag; QString objectsLinkLine; - QString quote; }; inline MingwMakefileGenerator::~MingwMakefileGenerator() diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 2f98eae075..6c2d2c6206 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -571,6 +571,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) addFilters(tempProj, xmlFilter, "Source Files"); addFilters(tempProj, xmlFilter, "Translation Files"); addFilters(tempProj, xmlFilter, "Deployment Files"); + addFilters(tempProj, xmlFilter, "Distribution Files"); for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) addFilters(tempProj, xmlFilter, tempProj.ExtraCompilers.at(x)); @@ -585,6 +586,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, xmlFilter, "Form Files"); outputFilter(tempProj, xml, xmlFilter, "Resource Files"); outputFilter(tempProj, xml, xmlFilter, "Deployment Files"); + outputFilter(tempProj, xml, xmlFilter, "Distribution Files"); for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) { outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x)); @@ -616,7 +618,6 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) bool isWinRT = false; bool isWinPhone = false; - bool isWinPhone80 = false; // ### Windows Phone 8.0, remove in Qt 5.4 for (int i = 0; i < tool.SingleProjects.count(); ++i) { xml << tag("ProjectConfiguration") << attrTag("Include" , tool.SingleProjects.at(i).Configuration.Name) @@ -625,7 +626,6 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << closetag(); isWinRT = isWinRT || tool.SingleProjects.at(i).Configuration.WinRT; isWinPhone = isWinPhone = tool.SingleProjects.at(i).Configuration.WinPhone; - isWinPhone80 = isWinPhone80 || tool.SingleProjects.at(i).Configuration.WinPhone80; } xml << closetag() @@ -637,18 +637,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) if (isWinRT) { xml << tagValue("MinimumVisualStudioVersion", tool.Version) - << tagValue("DefaultLanguage", "en"); - if (isWinPhone80) { - xml << tagValue("WinMDAssembly", "true"); - if (tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) { - xml << tagValue("XapOutputs", "true"); - xml << tagValue("XapFilename", "$(RootNamespace)_$(Configuration)_$(Platform).xap"); - } - } else { - xml << tagValue("AppContainerApplication", "true") - << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") - << tagValue("ApplicationTypeRevision", tool.SdkVersion); - } + << tagValue("DefaultLanguage", "en") + << tagValue("AppContainerApplication", "true") + << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") + << tagValue("ApplicationTypeRevision", tool.SdkVersion); } xml << closetag(); @@ -814,6 +806,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) addFilters(tool, xmlFilter, "Source Files"); addFilters(tool, xmlFilter, "Translation Files"); addFilters(tool, xmlFilter, "Deployment Files"); + addFilters(tool, xmlFilter, "Distribution Files"); for (int x = 0; x < tool.ExtraCompilers.count(); ++x) addFilters(tool, xmlFilter, tool.ExtraCompilers.at(x)); @@ -828,24 +821,15 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) outputFilter(tool, xml, xmlFilter, "Form Files"); outputFilter(tool, xml, xmlFilter, "Resource Files"); outputFilter(tool, xml, xmlFilter, "Deployment Files"); + outputFilter(tool, xml, xmlFilter, "Distribution Files"); for (int x = 0; x < tool.ExtraCompilers.count(); ++x) { outputFilter(tool, xml, xmlFilter, tool.ExtraCompilers.at(x)); } outputFilter(tool, xml, xmlFilter, "Root Files"); - if (isWinPhone80) { - xml << tag("ItemGroup") - << tag("Reference") - << attrTag("Include", "platform") - << attrTagS("IsWinMDFile", "true") - << attrTagS("Private", "false") - << closetag() - << closetag(); - } - // App manifest if (isWinRT) { - QString manifest = isWinPhone80 ? QStringLiteral("WMAppManifest.xml") : QStringLiteral("Package.appxmanifest"); + const QString manifest = QStringLiteral("Package.appxmanifest"); // Find all icons referenced in the manifest QSet<QString> icons; @@ -866,7 +850,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) // Write out manifest + icons as content items xml << tag(_ItemGroup) - << tag(isWinPhone80 ? "Xml" : "AppxManifest") + << tag("AppxManifest") << attrTag("Include", manifest) << closetag(); foreach (const QString &icon, icons) { @@ -877,12 +861,8 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml << closetag(); } - xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); - - if (isWinPhone80) - xml << import("Project", "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v8.0\\Microsoft.Cpp.WindowsPhone.8.0.targets"); - - xml << tag("ImportGroup") + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets") + << tag("ImportGroup") << attrTag("Label", "ExtensionTargets") << closetag(); } @@ -1935,11 +1915,11 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml fileAdded = true; xmlFilter << tag("CustomBuild") - << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTag("Include", Option::fixPathToTargetOS(filename)) << attrTagS("Filter", fullFilterName); xml << tag("CustomBuild") - << attrTag("Include",Option::fixPathToLocalOS(filename)); + << attrTag("Include", Option::fixPathToTargetOS(filename)); if (filter.Name.startsWith("Form Files") || filter.Name.startsWith("Generated Files") @@ -1979,11 +1959,13 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml } if ( !filter.CompilerTool.PrecompiledHeaderThrough.isEmpty() ) { - xml << tag("PrecompiledHeaderFile") << attrTag("Condition", condition) - << valueTag(filter.CompilerTool.PrecompiledHeaderThrough) - << tag("PrecompiledHeader") + << valueTag(filter.CompilerTool.PrecompiledHeaderThrough); + } + + if (filter.CompilerTool.UsePrecompiledHeader != pchUnset) { + xml << tag("PrecompiledHeader") << attrTag("Condition", condition) << valueTag(toString(filter.CompilerTool.UsePrecompiledHeader)); } @@ -1996,7 +1978,7 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml void VCXProjectWriter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &filePath, const QString &filterName) { - const QString nativeFilePath = Option::fixPathToLocalOS(filePath); + const QString nativeFilePath = Option::fixPathToTargetOS(filePath); if (filterName.startsWith("Source Files")) { xmlFilter << tag("ClCompile") << attrTag("Include", nativeFilePath) diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h index 68ba0eea83..1b7ce2d716 100644 --- a/qmake/generators/win32/msbuild_objectmodel.h +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 758db337ea..740c8c4d13 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -36,8 +36,9 @@ #include "cesdkhandler.h" #include <qregexp.h> -#include <qhash.h> #include <qdir.h> +#include <qdiriterator.h> +#include <qset.h> #include <windows/registry_p.h> @@ -55,7 +56,7 @@ static QString nmakePathList(const QStringList &list) .replace('#', QStringLiteral("^#")).replace('$', QStringLiteral("$$")); } -NmakeMakefileGenerator::NmakeMakefileGenerator() : Win32MakefileGenerator(), init_flag(false), usePCH(false) +NmakeMakefileGenerator::NmakeMakefileGenerator() : Win32MakefileGenerator(), usePCH(false) { } @@ -160,10 +161,7 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QString windowsPath; if (isPhone) { - if (targetVer == "WP80") // ### Windows Phone 8.0, remove in Qt 5.4 - windowsPath = "Microsoft\\Microsoft SDKs\\WindowsPhone\\v"; - else - windowsPath = "Microsoft\\Microsoft SDKs\\WindowsPhoneApp\\v"; + windowsPath = "Microsoft\\Microsoft SDKs\\WindowsPhoneApp\\v"; } else { windowsPath = "Microsoft\\Microsoft SDKs\\Windows\\v"; } @@ -184,8 +182,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QStringList binDirs; if (isPhone) { QString sdkDir = vcInstallDir; - if (targetVer == "WP80") - sdkDir += QStringLiteral("/WPSDK/") + targetVer; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" "Check that it is properly installed.\n", @@ -256,23 +252,21 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t) const QString root = "$(INSTALL_ROOT)"; ProStringList &uninst = project->values(ProKey(t + ".uninstall")); - QString targetdir = Option::fixPathToTargetOS(project->first(ProKey(t + ".path")).toQString(), false); - targetdir = fileFixify(targetdir, FileFixifyAbsolute); + QString targetdir = fileFixify(project->first(ProKey(t + ".path")).toQString(), FileFixifyAbsolute); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; if (project->isActiveConfig("debug_info")) { if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { QString pdb_target = getPdbTarget(); - pdb_target.remove('"'); QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target; QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute)); if(!ret.isEmpty()) ret += "\n\t"; - ret += QString("-$(INSTALL_FILE)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; + ret += QString("-$(INSTALL_FILE) ") + escapeFilePath(src_targ) + ' ' + escapeFilePath(dst_targ); if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + uninst.append("-$(DEL_FILE) " + escapeFilePath(dst_targ)); } } @@ -282,10 +276,6 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t) QStringList &NmakeMakefileGenerator::findDependencies(const QString &file) { QStringList &aList = MakefileGenerator::findDependencies(file); - // Note: The QMAKE_IMAGE_COLLECTION file have all images - // as dependency, so don't add precompiled header then - if (file == project->first("QMAKE_IMAGE_COLLECTION")) - return aList; for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { if(file.endsWith(*it)) { if(!precompObj.isEmpty() && !aList.contains(precompObj)) @@ -302,9 +292,12 @@ void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) // precompiled header if(usePCH) { - QString precompRule = QString("-c -Yc -Fp%1 -Fo%2").arg(precompPch).arg(precompObj); - t << precompObj << ": " << precompH << " " << escapeDependencyPaths(findDependencies(precompH)).join(" \\\n\t\t") - << "\n\t$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " << precompH << endl << endl; + QString precompRule = QString("-c -Yc -Fp%1 -Fo%2") + .arg(escapeFilePath(precompPch), escapeFilePath(precompObj)); + t << escapeDependencyPath(precompObj) << ": " << escapeDependencyPath(precompH) << ' ' + << escapeDependencyPaths(findDependencies(precompH)).join(" \\\n\t\t") + << "\n\t$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " + << escapeFilePath(precompH) << endl << endl; } } @@ -315,10 +308,9 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const || value == "QMAKE_RUN_CXX_IMP" || value == "QMAKE_RUN_CXX")) { QFileInfo precompHInfo(fileInfo(precompH)); + QString precompH_f = escapeFilePath(precompHInfo.fileName()); QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") - .arg(precompHInfo.fileName()) - .arg(precompHInfo.fileName()) - .arg(precompPch); + .arg(precompH_f, precompH_f, escapeFilePath(precompPch)); QString p = MakefileGenerator::var(value); p.replace("-c", precompRule); // Cannot use -Gm with -FI & -Yu, as this gives an @@ -339,10 +331,6 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const void NmakeMakefileGenerator::init() { - if(init_flag) - return; - init_flag = true; - /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") project->values("QMAKE_APP_FLAG").append("1"); @@ -352,16 +340,6 @@ void NmakeMakefileGenerator::init() MakefileGenerator::init(); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); - if(project->isEmpty("QMAKE_COPY_FILE")) - 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_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); return; } @@ -369,9 +347,7 @@ void NmakeMakefileGenerator::init() processVars(); - if (!project->values("RES_FILE").isEmpty()) { - project->values("QMAKE_LIBS") += escapeFilePaths(project->values("RES_FILE")); - } + project->values("QMAKE_LIBS") += project->values("RES_FILE"); if (!project->values("DEF_FILE").isEmpty()) { QString defFileName = fileFixify(project->first("DEF_FILE").toQString()); @@ -412,6 +388,7 @@ void NmakeMakefileGenerator::init() ProString version = project->first("TARGET_VERSION_EXT"); if(project->isActiveConfig("shared")) { project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); + project->values("QMAKE_DISTCLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".lib"); } if (project->isActiveConfig("debug_info")) { QString pdbfile = project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"; @@ -430,6 +407,17 @@ void NmakeMakefileGenerator::init() } } +QStringList NmakeMakefileGenerator::sourceFilesForImplicitRulesFilter() +{ + QStringList filter; + const QChar wildcard = QLatin1Char('*'); + foreach (const QString &ext, Option::c_ext) + filter << wildcard + ext; + foreach (const QString &ext, Option::cpp_ext) + filter << wildcard + ext; + return filter; +} + void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) { t << ".SUFFIXES:"; @@ -439,20 +427,17 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) t << " " << (*cppit); t << endl << endl; - if(!project->isActiveConfig("no_batch")) { - // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC - project->variables().remove("QMAKE_RUN_CXX"); - project->variables().remove("QMAKE_RUN_CC"); - - QHash<QString, void*> source_directories; - source_directories.insert(".", (void*)1); + bool useInferenceRules = !project->isActiveConfig("no_batch"); + QSet<QString> source_directories; + if (useInferenceRules) { + source_directories.insert("."); static const char * const directories[] = { "UI_SOURCES_DIR", "UI_DIR", 0 }; for (int y = 0; directories[y]; y++) { QString dirTemp = project->first(directories[y]).toQString(); if (dirTemp.endsWith("\\")) dirTemp.truncate(dirTemp.length()-1); if(!dirTemp.isEmpty()) - source_directories.insert(dirTemp, (void*)1); + source_directories.insert(dirTemp); } static const char * const srcs[] = { "SOURCES", "GENERATED_SOURCES", 0 }; for (int x = 0; srcs[x]; x++) { @@ -462,23 +447,59 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) if((*sit).indexOf(sep) == -1) sep = "/"; QString dir = (*sit).toQString().section(sep, 0, -2); - if(!dir.isEmpty() && !source_directories[dir]) - source_directories.insert(dir, (void*)1); + if (!dir.isEmpty()) + source_directories.insert(dir); } } - for(QHash<QString, void*>::Iterator it(source_directories.begin()); it != source_directories.end(); ++it) { - if(it.key().isEmpty()) + // nmake's inference rules might pick up the wrong files when encountering source files with + // the same name in different directories. In this situation, turn inference rules off. + QHash<QString, QString> fileNames; + bool duplicatesFound = false; + const QStringList sourceFilesFilter = sourceFilesForImplicitRulesFilter(); + QStringList fixifiedSourceDirs = fileFixify(source_directories.toList(), FileFixifyAbsolute); + fixifiedSourceDirs.removeDuplicates(); + foreach (const QString &sourceDir, fixifiedSourceDirs) { + QDirIterator dit(sourceDir, sourceFilesFilter, QDir::Files | QDir::NoDotAndDotDot); + while (dit.hasNext()) { + dit.next(); + QString &duplicate = fileNames[dit.fileName()]; + if (duplicate.isNull()) { + duplicate = dit.filePath(); + } else { + warn_msg(WarnLogic, "%s conflicts with %s", qPrintable(duplicate), + qPrintable(dit.filePath())); + duplicatesFound = true; + } + } + } + if (duplicatesFound) { + useInferenceRules = false; + warn_msg(WarnLogic, "Automatically turning off nmake's inference rules. (CONFIG += no_batch)"); + } + } + + if (useInferenceRules) { + // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC + project->variables().remove("QMAKE_RUN_CXX"); + project->variables().remove("QMAKE_RUN_CC"); + + foreach (const QString &sourceDir, source_directories) { + if (sourceDir.isEmpty()) continue; QString objDir = var("OBJECTS_DIR"); if (objDir == ".\\") objDir = ""; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << "{" << it.key() << "}" << (*cppit) << "{" << objDir << "}" << Option::obj_ext << "::\n\t" - << var("QMAKE_RUN_CXX_IMP_BATCH").replace(QRegExp("\\$@"), var("OBJECTS_DIR")) << endl << "\t$<\n<<\n\n"; + t << '{' << escapeDependencyPath(sourceDir) << '}' << (*cppit) + << '{' << escapeDependencyPath(objDir) << '}' << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CXX_IMP_BATCH").replace(QRegExp("\\$@"), fileVar("OBJECTS_DIR")) + << "\n\t$<\n<<\n\n"; for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) - t << "{" << it.key() << "}" << (*cit) << "{" << objDir << "}" << Option::obj_ext << "::\n\t" - << var("QMAKE_RUN_CC_IMP_BATCH").replace(QRegExp("\\$@"), var("OBJECTS_DIR")) << endl << "\t$<\n<<\n\n"; + t << '{' << escapeDependencyPath(sourceDir) << '}' << (*cit) + << '{' << escapeDependencyPath(objDir) << '}' << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CC_IMP_BATCH").replace(QRegExp("\\$@"), fileVar("OBJECTS_DIR")) + << "\n\t$<\n<<\n\n"; } } else { for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) @@ -494,8 +515,9 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) const ProString templateName = project->first("TEMPLATE"); t << "first: all\n"; - t << "all: " << fileFixify(Option::output.fileName()) << " " << varGlue("ALL_DEPS"," "," "," ") << "$(DESTDIR_TARGET)\n\n"; - t << "$(DESTDIR_TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS"); + t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) + << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n"; + t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <<var("QMAKE_PRE_LINK"); @@ -519,12 +541,12 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) if (linkerSupportsEmbedding) { extraLFlags = "/MANIFEST:embed"; } else { - manifest = escapeFilePath(target + ".embed.manifest"); - extraLFlags += "/MANIFEST /MANIFESTFILE:" + manifest; + manifest = target + ".embed.manifest"; + extraLFlags += "/MANIFEST /MANIFESTFILE:" + escapeFilePath(manifest); project->values("QMAKE_CLEAN") << manifest; } } else { - manifest = escapeFilePath(fileFixify(manifest)); + manifest = fileFixify(manifest); } const QString resourceId = (templateName == "app") ? "1" : "2"; @@ -532,16 +554,19 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) if (incrementalLinking && !linkerSupportsEmbedding) { // Link a resource that contains the manifest without modifying the exe/dll after linking. - QString manifest_rc = escapeFilePath(target + "_manifest.rc"); - QString manifest_res = escapeFilePath(target + "_manifest.res"); - QString manifest_bak = escapeFilePath(target + "_manifest.bak"); + QString manifest_rc = target + "_manifest.rc"; + QString manifest_res = target + "_manifest.res"; project->values("QMAKE_CLEAN") << manifest_rc << manifest_res; + manifest_rc = escapeFilePath(manifest_rc); + manifest_res = escapeFilePath(manifest_res); t << "\n\techo " << resourceId << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ " - << cQuoted(unescapeFilePath(manifest)) << ">" << manifest_rc; + << cQuoted(manifest) << '>' << manifest_rc; if (generateManifest) { + manifest = escapeFilePath(manifest); + QString manifest_bak = escapeFilePath(target + "_manifest.bak"); t << "\n\tif not exist $(DESTDIR_TARGET) if exist " << manifest << " del " << manifest; t << "\n\tif exist " << manifest << " copy /Y " << manifest << ' ' << manifest_bak; @@ -563,7 +588,7 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) t << "\n\t"; writeLinkCommand(t, extraLFlags); if (!linkerSupportsEmbedding) { - t << "\n\tmt.exe /nologo /manifest " << manifest + t << "\n\tmt.exe /nologo /manifest " << escapeFilePath(manifest) << " /outputresource:$(DESTDIR_TARGET);" << resourceId; } } @@ -576,7 +601,7 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"); if(useSignature) { - t << "\n\tsigntool sign /F " << signature << " $(DESTDIR_TARGET)"; + t << "\n\tsigntool sign /F " << escapeFilePath(signature) << " $(DESTDIR_TARGET)"; } if(!project->isEmpty("QMAKE_POST_LINK")) { t << "\n\t" << var("QMAKE_POST_LINK"); diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 753223b98e..83ce96c8b7 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -40,7 +40,6 @@ QT_BEGIN_NAMESPACE class NmakeMakefileGenerator : public Win32MakefileGenerator { - bool init_flag; void writeNmakeParts(QTextStream &); bool writeMakefile(QTextStream &); void writeImplicitRulesPart(QTextStream &t); @@ -48,6 +47,7 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString()); int msvcVersion() const; void init(); + static QStringList sourceFilesForImplicitRulesFilter(); protected: virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix, diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 74a0a20ea2..917f4467a0 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -2137,7 +2137,6 @@ VCPreLinkEventTool::VCPreLinkEventTool() VCConfiguration::VCConfiguration() : WinRT(false), WinPhone(false), - WinPhone80(false), ATLMinimizesCRunTimeLibraryUsage(unset), BuildBrowserInformation(unset), CharacterSet(charSetNotSet), @@ -2237,7 +2236,8 @@ void VCFilter::modifyPCHstage(QString str) useCompilerTool = true; // Setup PCH options CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); - CompilerTool.PrecompiledHeaderThrough = (isCPPFile ? Project->precompHFilename : QString("$(NOINHERIT)")); + if (isCFile) + CompilerTool.PrecompiledHeaderThrough = QLatin1String("$(NOINHERIT)"); CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); } @@ -2295,9 +2295,8 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) QString cmd, cmd_name, out; QStringList deps, inputs; // Variabel replacement of output name - out = Option::fixPathToTargetOS( - Project->replaceExtraCompilerVariables(tmp_out, inFile, QString()), - false); + out = Option::fixPathToTargetOS(Project->replaceExtraCompilerVariables( + tmp_out, inFile, QString(), MakefileGenerator::NoShell), false); // If file has built-in compiler, we've swapped the input and output of // the command, as we in Visual Studio cannot have a Custom Buildstep on @@ -2318,9 +2317,8 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) if (!tmp_dep_cmd.isEmpty()) { // Execute dependency command, and add every line as a dep char buff[256]; - QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd, - Option::fixPathToLocalOS(inFile, true, false), - out); + QString dep_cmd = Project->replaceExtraCompilerVariables( + tmp_dep_cmd, inFile, out, MakefileGenerator::LocalShell); if(Project->canExecute(dep_cmd)) { dep_cmd.prepend(QLatin1String("cd ") + Project->escapeFilePath(Option::fixPathToLocalOS(Option::output_dir, false)) @@ -2347,8 +2345,9 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) } for (int i = 0; i < deps.count(); ++i) deps[i] = Option::fixPathToTargetOS( - Project->replaceExtraCompilerVariables(deps.at(i), inFile, out), - false).trimmed(); + Project->replaceExtraCompilerVariables( + deps.at(i), inFile, out, MakefileGenerator::NoShell), + false); // Command for file if (combined) { // Add dependencies for each file @@ -2364,28 +2363,27 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) deps = inputs + deps; // input files themselves too.. // Replace variables for command w/all input files - // ### join gives path issues with directories containing spaces! cmd = Project->replaceExtraCompilerVariables(tmp_cmd, - inputs.join(' '), - out); + inputs, + QStringList(out), + MakefileGenerator::TargetShell); } else { deps.prepend(inFile); // input file itself too.. cmd = Project->replaceExtraCompilerVariables(tmp_cmd, inFile, - out); + out, + MakefileGenerator::TargetShell); } // Name for command if (!tmp_cmd_name.isEmpty()) { - cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out); + cmd_name = Project->replaceExtraCompilerVariables( + tmp_cmd_name, inFile, out, MakefileGenerator::NoShell); } else { int space = cmd.indexOf(' '); if (space != -1) cmd_name = cmd.left(space); else cmd_name = cmd; - if ((cmd_name[0] == '\'' || cmd_name[0] == '"') && - cmd_name[0] == cmd_name[cmd_name.length()-1]) - cmd_name = cmd_name.mid(1,cmd_name.length()-2); } // Fixify paths @@ -2451,6 +2449,8 @@ const VCFilter &VCProjectSingleConfig::filterByName(const QString &name) const return ResourceFiles; if (name == "Deployment Files") return DeploymentFiles; + if (name == "Distribution Files") + return DistributionFiles; return filterForExtraCompiler(name); } @@ -2533,6 +2533,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, "Form Files"); outputFilter(tempProj, xml, "Resource Files"); outputFilter(tempProj, xml, "Deployment Files"); + outputFilter(tempProj, xml, "Distribution Files"); QSet<QString> extraCompilersInProject; for (int i = 0; i < tool.ExtraCompilersFiles.count(); ++i) { @@ -2586,6 +2587,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProject &tool) outputFilter(tool, xml, "Form Files"); outputFilter(tool, xml, "Resource Files"); outputFilter(tool, xml, "Deployment Files"); + outputFilter(tool, xml, "Distribution Files"); for (int x = 0; x < tool.ExtraCompilers.count(); ++x) { outputFilter(tool, xml, tool.ExtraCompilers.at(x)); } @@ -2903,7 +2905,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCFilter &tool) for (int i = 0; i < tool.Files.count(); ++i) { const VCFilterFile &info = tool.Files.at(i); xml << tag(q_File) - << attrS(_RelativePath, Option::fixPathToLocalOS(info.file)) + << attrS(_RelativePath, Option::fixPathToTargetOS(info.file)) << data(); // In case no custom builds, to avoid "/>" endings outputFileConfig(tool, xml, tool.Files.at(i).file); xml << closetag(q_File); @@ -2962,7 +2964,7 @@ void VCProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, const QSt void VCProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, const VCFilterFile &info, const QString &filtername) { xml << tag(q_File) - << attrS(_RelativePath, Option::fixPathToLocalOS(info.file)); + << attrS(_RelativePath, Option::fixPathToTargetOS(info.file)); for (int i = 0; i < project.SingleProjects.count(); ++i) { VCFilter filter = project.SingleProjects.at(i).filterByName(filtername); if (filter.Config) // only if the filter is not empty diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 4b70ca3d71..59136b16c8 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -873,7 +873,7 @@ public: bool suppressUnknownOptionWarnings; DotNET CompilerVersion; - bool WinRT, WinPhone, WinPhone80; + bool WinRT, WinPhone; // Variables triState ATLMinimizesCRunTimeLibraryUsage; @@ -1010,6 +1010,7 @@ public: VCFilter FormFiles; VCFilter ResourceFiles; VCFilter DeploymentFiles; + VCFilter DistributionFiles; VCFilterList ExtraCompilersFiles; bool flat_files; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index e3031d559c..4822bcf22a 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -56,6 +56,7 @@ const char _GUIDTranslationFiles[] = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} const char _GUIDFormFiles[] = "{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"; const char _GUIDExtraCompilerFiles[] = "{E0D8C965-CC5F-43d7-AD63-FAEF0BBC0F85}"; const char _GUIDDeploymentFiles[] = "{D9D6E243-F8AF-46E4-B9FD-80ECBC20BA3E}"; +const char _GUIDDistributionFiles[] = "{B83CAF91-C7BF-462F-B76C-EA11631F866C}"; QT_END_NAMESPACE #ifdef Q_OS_WIN32 @@ -208,7 +209,6 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos VcprojGenerator::VcprojGenerator() : Win32MakefileGenerator(), - init_flag(false), is64Bit(false), projectWriter(0) { @@ -325,7 +325,8 @@ QUuid VcprojGenerator::getProjectUUID(const QString &filename) // If none, create one based on the MD5 of absolute project path if(uuid.isNull() || !filename.isEmpty()) { - QString abspath = Option::fixPathToLocalOS(filename.isEmpty()?project->first("QMAKE_MAKEFILE").toQString():filename); + QString abspath = Option::fixPathToTargetOS( + filename.isEmpty() ? project->first("QMAKE_MAKEFILE").toQString() : filename); QByteArray digest = QCryptographicHash::hash(abspath.toUtf8(), QCryptographicHash::Sha1); memcpy((unsigned char*)(&uuid), digest.constData(), sizeof(QUuid)); validUUID = !uuid.isNull(); @@ -458,14 +459,14 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt while (collectedIt.hasNext()) { QPair<QString, ProStringList> subdir = collectedIt.next(); QString profile = subdir.first; - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(profile, true))); + QFileInfo fi(fileInfo(Option::normalizePath(profile))); if (fi.exists()) { if (fi.isDir()) { if (!profile.endsWith(Option::dir_sep)) profile += Option::dir_sep; profile += fi.baseName() + Option::pro_ext; QString profileKey = fi.absoluteFilePath(); - fi = QFileInfo(fileInfo(Option::fixPathToLocalOS(profile, true))); + fi = QFileInfo(fileInfo(Option::normalizePath(profile))); if (!fi.exists()) continue; projLookup.insert(profileKey, fi.absoluteFilePath()); @@ -506,7 +507,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt Option::qmake_mode = old_mode; // We assume project filename is [QMAKE_PROJECT_NAME].vcproj - QString vcproj = unescapeFilePath(tmp_vcproj.project->first("QMAKE_PROJECT_NAME") + project->first("VCPROJ_EXTENSION")); + QString vcproj = tmp_vcproj.project->first("QMAKE_PROJECT_NAME") + project->first("VCPROJ_EXTENSION"); QString vcprojDir = qmake_getpwd(); // If file doesn't exsist, then maybe the users configuration @@ -536,7 +537,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt VcsolutionDepend *newDep = new VcsolutionDepend; newDep->vcprojFile = vcprojDir + Option::dir_sep + vcproj; - newDep->orig_target = unescapeFilePath(tmp_proj.first("QMAKE_ORIG_TARGET")).toQString(); + newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET").toQString(); newDep->target = tmp_proj.first("MSVCPROJ_TARGET").toQString().section(Option::dir_sep, -1); newDep->targetType = tmp_vcproj.projectTarget; newDep->uuid = tmp_proj.isEmpty("QMAKE_UUID") ? getProjectUUID(Option::fixPathToLocalOS(vcprojDir + QDir::separator() + vcproj)).toString().toUpper(): tmp_proj.first("QMAKE_UUID").toQString(); @@ -672,6 +673,7 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) // write out projects for (QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) { + // ### quoting rules? t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid << "\"" << (*it)->orig_target << "\", \"" << (*it)->vcprojFile << "\", \"" << (*it)->uuid << "\""; @@ -767,9 +769,6 @@ bool VcprojGenerator::hasBuiltinCompiler(const QString &file) void VcprojGenerator::init() { - if (init_flag) - return; - init_flag = true; is64Bit = (project->first("QMAKE_TARGET.arch") == "x86_64"); projectWriter = createProjectWriter(); @@ -798,15 +797,53 @@ void VcprojGenerator::init() } MakefileGenerator::init(); - initOld(); // Currently calling old DSP code to set variables. CLEAN UP! + + // $$QMAKE.. -> $$MSVCPROJ.. ------------------------------------- + const ProStringList &incs = project->values("INCLUDEPATH"); + for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) { + QString inc = (*incit).toQString(); + project->values("MSVCPROJ_INCPATH").append("-I" + escapeFilePath(inc)); + } + + QString dest = Option::fixPathToTargetOS(project->first("TARGET").toQString()) + project->first("TARGET_EXT"); + project->values("MSVCPROJ_TARGET") = ProStringList(dest); + + // DLL COPY ------------------------------------------------------ + if (project->isActiveConfig("dll") && !project->values("DLLDESTDIR").isEmpty()) { + const ProStringList &dlldirs = project->values("DLLDESTDIR"); + QString copydll(""); + ProStringList::ConstIterator dlldir; + for (dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir) { + if (!copydll.isEmpty()) + copydll += " && "; + copydll += "copy \"$(TargetPath)\" " + escapeFilePath(*dlldir); + } + + QString deststr("Copy " + dest + " to "); + for (dlldir = dlldirs.begin(); dlldir != dlldirs.end();) { + deststr += *dlldir; + ++dlldir; + if (dlldir != dlldirs.end()) + deststr += ", "; + } + + project->values("MSVCPROJ_COPY_DLL").append(copydll); + project->values("MSVCPROJ_COPY_DLL_DESC").append(deststr); + } + +#if 0 + // Verbose output if "-d -d"... + qDebug("Generator: MSVC.NET: List of current variables:"); + for (ProValueMap::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) + qDebug("Generator: MSVC.NET: %s => %s", qPrintable(it.key().toQString()), qPrintable(it.value().join(" | "))); +#endif // Figure out what we're trying to build if(project->first("TEMPLATE") == "vcapp") { projectTarget = Application; } else if(project->first("TEMPLATE") == "vclib") { if(project->isActiveConfig("staticlib")) { - if (!project->values("RES_FILE").isEmpty()) - project->values("QMAKE_LIBS") += escapeFilePaths(project->values("RES_FILE")); + project->values("QMAKE_LIBS") += project->values("RES_FILE"); projectTarget = StaticLib; } else projectTarget = SharedLib; @@ -819,7 +856,7 @@ void VcprojGenerator::init() if (usePCH) { precompHFilename = fileInfo(precompH).fileName(); // Created files - QString origTarget = unescapeFilePath(project->first("QMAKE_ORIG_TARGET").toQString()); + QString origTarget = project->first("QMAKE_ORIG_TARGET").toQString(); precompObj = origTarget + Option::obj_ext; precompPch = origTarget + ".pch"; // Add PRECOMPILED_HEADER to HEADERS @@ -856,7 +893,7 @@ void VcprojGenerator::init() extraCompilerSources[file] += quc.toQString(); } else { QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables( - compiler_out, file, QString()), false); + compiler_out, file, QString(), NoShell), false); extraCompilerSources[out] += quc.toQString(); extraCompilerOutputs[out] = QStringList(file); // Can only have one } @@ -907,15 +944,11 @@ void VcprojGenerator::initProject() initTranslationFiles(); initFormFiles(); initResourceFiles(); + initDistributionFiles(); initExtraCompilerOutputs(); - if (vcProject.Configuration.WinRT) { - if (vcProject.Configuration.WinPhone80 - && vcProject.Configuration.ConfigurationType == typeApplication) - initWMAppManifest(); - } // Own elements ----------------------------- - vcProject.Name = unescapeFilePath(project->first("QMAKE_ORIG_TARGET").toQString()); + vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { case NET2013: vcProject.Version = "12.00"; @@ -1020,7 +1053,6 @@ void VcprojGenerator::initConfiguration() conf.WinRT = project->isActiveConfig("winrt"); if (conf.WinRT) { conf.WinPhone = project->isActiveConfig("winphone"); - conf.WinPhone80 = project->first("WINTARGET_VER") == "WP80"; // Saner defaults conf.compiler.UsePrecompiledHeader = pchNone; conf.compiler.CompileAsWinRT = _False; @@ -1148,7 +1180,7 @@ void VcprojGenerator::initLinkerTool() ProStringList l = ProStringList(libs); conf.linker.parseOptions(l); } else { - conf.linker.AdditionalDependencies += libs.toQString(); + conf.linker.AdditionalDependencies << escapeFilePath(libs.toQString()); } } @@ -1208,7 +1240,7 @@ void VcprojGenerator::initPostBuildEventTools() !project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"); if (useSignature) { conf.postBuild.CommandLine.prepend( - QLatin1String("signtool sign /F ") + signature + QLatin1String(" \"$(TargetPath)\"")); + QLatin1String("signtool sign /F ") + escapeFilePath(signature) + QLatin1String(" \"$(TargetPath)\"")); conf.postBuild.ExcludedFromBuild = _False; } @@ -1239,8 +1271,7 @@ void VcprojGenerator::initDeploymentTool() // Only deploy Qt libs for shared build if (!project->values("QMAKE_QT_DLL").isEmpty()) { // FIXME: This code should actually resolve the libraries from all Qt modules. - const QString &qtdir = QLibraryInfo::rawLocation(QLibraryInfo::LibrariesPath, - QLibraryInfo::EffectivePaths); + const QString &qtdir = project->propertyValue(ProKey("QT_INSTALL_LIBS/get")).toQString(); ProStringList arg = project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE"); for (ProStringList::ConstIterator it = arg.constBegin(); it != arg.constEnd(); ++it) { if (it->contains(qtdir)) { @@ -1316,13 +1347,13 @@ void VcprojGenerator::initDeploymentTool() || devicePath.at(0) == QLatin1Char('\\') || devicePath.at(0) == QLatin1Char('%'))) { // create output path - devicePath = Option::fixPathToLocalOS(QDir::cleanPath(targetPath + QLatin1Char('\\') + devicePath)); + devicePath = Option::fixPathToTargetOS(targetPath + QLatin1Char('\\') + devicePath); } } // foreach d in item.files foreach (const ProString &src, project->values(ProKey(item + ".files"))) { QString itemDevicePath = devicePath; - QString source = Option::fixPathToLocalOS(src.toQString()); + QString source = Option::normalizePath(src.toQString()); QString nameFilter; QFileInfo info(source); QString searchPath; @@ -1331,7 +1362,7 @@ void VcprojGenerator::initDeploymentTool() itemDevicePath += "\\" + info.fileName(); searchPath = info.absoluteFilePath(); } else { - nameFilter = source.split('\\').last(); + nameFilter = info.fileName(); searchPath = info.absolutePath(); } @@ -1343,10 +1374,10 @@ void VcprojGenerator::initDeploymentTool() while(iterator.hasNext()) { iterator.next(); if (conf.WinRT) { - QString absoluteItemFilePath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absoluteFilePath()); + QString absoluteItemFilePath = Option::fixPathToTargetOS(QFileInfo(iterator.filePath()).absoluteFilePath()); vcProject.DeploymentFiles.addFile(absoluteItemFilePath); } else { - QString absoluteItemPath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absolutePath()); + QString absoluteItemPath = Option::fixPathToTargetOS(QFileInfo(iterator.filePath()).absolutePath()); // Identify if it is just another subdir int diffSize = absoluteItemPath.size() - pathSize; // write out rules @@ -1441,7 +1472,6 @@ void VcprojGenerator::initGeneratedFiles() vcProject.GeneratedFiles.addFiles(project->values("IDLSOURCES")); if (project->values("RC_FILE").isEmpty()) vcProject.GeneratedFiles.addFiles(project->values("RES_FILE")); - vcProject.GeneratedFiles.addFiles(project->values("QMAKE_IMAGE_COLLECTION")); // compat if(!extraCompilerOutputs.isEmpty()) vcProject.GeneratedFiles.addFiles(extraCompilerOutputs.keys()); @@ -1503,7 +1533,8 @@ void VcprojGenerator::initResourceFiles() if(!qrc_files.isEmpty()) { for (int i = 0; i < qrc_files.count(); ++i) { char buff[256]; - QString dep_cmd = replaceExtraCompilerVariables(rcc_dep_cmd, qrc_files.at(i).toQString(), ""); + QString dep_cmd = replaceExtraCompilerVariables( + rcc_dep_cmd, qrc_files.at(i).toQString(), QString(), LocalShell); dep_cmd = Option::fixPathToLocalOS(dep_cmd, true, false); if(canExecute(dep_cmd)) { @@ -1531,12 +1562,22 @@ void VcprojGenerator::initResourceFiles() // You may look again -------------------------------------------- vcProject.ResourceFiles.addFiles(project->values("RESOURCES")); - vcProject.ResourceFiles.addFiles(project->values("IMAGES")); vcProject.ResourceFiles.Project = this; vcProject.ResourceFiles.Config = &(vcProject.Configuration); } +void VcprojGenerator::initDistributionFiles() +{ + vcProject.DistributionFiles.Name = "Distribution Files"; + vcProject.DistributionFiles.ParseFiles = _False; + vcProject.DistributionFiles.Filter = "*"; + vcProject.DistributionFiles.Guid = _GUIDDistributionFiles; + vcProject.DistributionFiles.addFiles(project->values("DISTFILES")); + vcProject.DistributionFiles.Project = this; + vcProject.DistributionFiles.Config = &(vcProject.Configuration); +} + void VcprojGenerator::initExtraCompilerOutputs() { ProStringList otherFilters; @@ -1545,9 +1586,7 @@ void VcprojGenerator::initExtraCompilerOutputs() << "GENERATED_SOURCES" << "HEADERS" << "IDLSOURCES" - << "IMAGES" << "LEXSOURCES" - << "QMAKE_IMAGE_COLLECTION" << "RC_FILE" << "RESOURCES" << "RES_FILE" @@ -1579,16 +1618,16 @@ void VcprojGenerator::initExtraCompilerOutputs() QString tmp_out = project->first(ProKey(*it + ".output")).toQString(); if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) { // Combined output, only one file result - extraCompile.addFile( - Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, QString(), QString()), false)); + extraCompile.addFile(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell), false)); } else { // One output file per input const ProStringList &tmp_in = project->values(project->first(ProKey(*it + ".input")).toKey()); for (int i = 0; i < tmp_in.count(); ++i) { const QString &filename = tmp_in.at(i).toQString(); if (extraCompilerSources.contains(filename)) - extraCompile.addFile( - Option::fixPathToTargetOS(replaceExtraCompilerVariables(filename, tmp_out, QString()), false)); + extraCompile.addFile(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(filename, tmp_out, QString(), NoShell), false)); } } } else { @@ -1603,8 +1642,8 @@ void VcprojGenerator::initExtraCompilerOutputs() for (int i = 0; i < tmp_in.count(); ++i) { const QString &filename = tmp_in.at(i).toQString(); if (extraCompilerSources.contains(filename)) - extraCompile.addFile( - Option::fixPathToTargetOS(replaceExtraCompilerVariables(filename, QString(), QString()), false)); + extraCompile.addFile(Option::fixPathToTargetOS( + replaceExtraCompilerVariables(filename, QString(), QString(), NoShell), false)); } } } @@ -1616,109 +1655,6 @@ void VcprojGenerator::initExtraCompilerOutputs() } } -void VcprojGenerator::initWMAppManifest() -{ - if (!project->isActiveConfig("autogen_wmappmanifest")) - return; - - // autogen_wmappmanifest - QFile file(Option::output_dir + "\\WMAppManifest.xml"); - if (!file.open(QFile::WriteOnly)) - return; - - QTextStream stream(&file); - - QString productID = project->first("PRODUCTID").toQString(); - QString target = project->first("TARGET").toQString(); - QString author = project->first("AUTHOR").toQString(); - QString publisher = project->first("PUBLISHER").toQString(); - QString publisherID = project->first("PUBLISHERID").toQString(); - QString description = project->first("DESCRIPTION").toQString(); - - if (author.isEmpty()) - author = "Qt"; - if (publisher.isEmpty()) - publisher = "Qt"; - if (productID.isEmpty()) - productID = QUuid::createUuid().toString(); - if (publisherID.isEmpty()) - publisherID = QUuid::createUuid().toString(); - - stream << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - << "<Deployment xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\" AppPlatformVersion=\"8.0\">\n" - << " <DefaultLanguage xmlns=\"\" code=\"en-US\"/>\n" - << " <App xmlns=\"\" ProductID=\"" << productID << "\" Title=\"" << target - << "\" RuntimeType=\"Modern Native\" Version=\"1.0.0.0\"" - << " Genre=\"apps.normal\" Author=\"" << author - << "\" Description=\"" << description << "\" Publisher=\"" << publisher - << "\" PublisherID=\"" << publisherID << "\">\n" - << " <IconPath IsRelative=\"true\" IsResource=\"false\">ApplicationIcon.png</IconPath>\n" - << " <Capabilities>\n" - << " <Capability Name=\"ID_CAP_NETWORKING\" />\n" - << " <Capability Name=\"ID_CAP_MEDIALIB_AUDIO\" />\n" - << " <Capability Name=\"ID_CAP_MEDIALIB_PLAYBACK\" />\n" - << " </Capabilities>\n" - << " <Tasks>\n" - << " <DefaultTask Name=\"_default\" ImagePath=\"" << target << ".exe\" ImageParams=\"\" />\n" - << " </Tasks>\n" - << " <Tokens>\n" - << " <PrimaryToken TokenID=\"" << target << "Token\" TaskName=\"_default\">\n" - << " <TemplateType5>\n" - << " <Count>0</Count>\n" - << " <Title>" << target << "</Title>\n" - << " </TemplateType5>\n" - << " </PrimaryToken>\n" - << " </Tokens>\n" - << " <ScreenResolutions>\n" - << " <ScreenResolution Name=\"ID_RESOLUTION_WVGA\" />\n" - << " <ScreenResolution Name=\"ID_RESOLUTION_WXGA\" />\n" - << " <ScreenResolution Name=\"ID_RESOLUTION_HD720P\" />\n" - << " </ScreenResolutions>\n" - << " </App>\n" - << "</Deployment>\n"; -} - -void VcprojGenerator::initOld() -{ - // $$QMAKE.. -> $$MSVCPROJ.. ------------------------------------- - const ProStringList &incs = project->values("INCLUDEPATH"); - for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) { - QString inc = (*incit).toQString(); - if (!inc.startsWith('"') && !inc.endsWith('"')) - inc = QString("\"%1\"").arg(inc); // Quote all paths if not quoted already - project->values("MSVCPROJ_INCPATH").append("-I" + inc); - } - - QString dest = Option::fixPathToTargetOS(project->first("TARGET").toQString()) + project->first("TARGET_EXT"); - project->values("MSVCPROJ_TARGET") = ProStringList(dest); - - // DLL COPY ------------------------------------------------------ - if(project->isActiveConfig("dll") && !project->values("DLLDESTDIR").isEmpty()) { - const ProStringList &dlldirs = project->values("DLLDESTDIR"); - QString copydll(""); - ProStringList::ConstIterator dlldir; - for(dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir) { - if(!copydll.isEmpty()) - copydll += " && "; - copydll += "copy \"$(TargetPath)\" \"" + *dlldir + "\""; - } - - QString deststr("Copy " + dest + " to "); - for(dlldir = dlldirs.begin(); dlldir != dlldirs.end();) { - deststr += *dlldir; - ++dlldir; - if(dlldir != dlldirs.end()) - deststr += ", "; - } - - project->values("MSVCPROJ_COPY_DLL").append(copydll); - project->values("MSVCPROJ_COPY_DLL_DESC").append(deststr); - } - - // Verbose output if "-d -d"... - outputVariables(); -} - // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ @@ -1727,9 +1663,10 @@ VCProjectWriter *VcprojGenerator::createProjectWriter() return new VCProjectWriter; } -QString VcprojGenerator::replaceExtraCompilerVariables(const QString &var, const QStringList &in, const QStringList &out) +QString VcprojGenerator::replaceExtraCompilerVariables( + const QString &var, const QStringList &in, const QStringList &out, ReplaceFor forShell) { - QString ret = MakefileGenerator::replaceExtraCompilerVariables(var, in, out); + QString ret = MakefileGenerator::replaceExtraCompilerVariables(var, in, out, forShell); ProStringList &defines = project->values("VCPROJ_MAKEFILE_DEFINES"); if(defines.isEmpty()) @@ -1757,7 +1694,7 @@ bool VcprojGenerator::openOutput(QFile &file, const QString &/*build*/) const ProString ext = project->first("VCPROJ_EXTENSION"); if(project->first("TEMPLATE") == "vcsubdirs") ext = project->first("VCSOLUTION_EXTENSION"); - ProString outputName = unescapeFilePath(project->first("TARGET")); + ProString outputName = project->first("TARGET"); if (!project->first("MAKEFILE").isEmpty()) outputName = project->first("MAKEFILE"); file.setFileName(outdir + outputName + ext); @@ -1765,29 +1702,4 @@ bool VcprojGenerator::openOutput(QFile &file, const QString &/*build*/) const return Win32MakefileGenerator::openOutput(file, QString()); } -QString VcprojGenerator::fixFilename(QString ofile) const -{ - ofile = Option::fixPathToLocalOS(ofile); - int slashfind = ofile.lastIndexOf(Option::dir_sep); - if(slashfind == -1) { - ofile = ofile.replace('-', '_'); - } else { - int hyphenfind = ofile.indexOf('-', slashfind); - while (hyphenfind != -1 && slashfind < hyphenfind) { - ofile = ofile.replace(hyphenfind, 1, '_'); - hyphenfind = ofile.indexOf('-', hyphenfind + 1); - } - } - return ofile; -} - -void VcprojGenerator::outputVariables() -{ -#if 0 - qDebug("Generator: MSVC.NET: List of current variables:"); - for (ProValueMap::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) - qDebug("Generator: MSVC.NET: %s => %s", qPrintable(it.key().toQString()), qPrintable(it.value().join(" | "))); -#endif -} - QT_END_NAMESPACE diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index f436b6da20..3396ea4986 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -49,7 +49,6 @@ class QUuid; struct VcsolutionDepend; class VcprojGenerator : public Win32MakefileGenerator { - bool init_flag; bool is64Bit; bool writeVcprojParts(QTextStream &); @@ -77,18 +76,16 @@ protected: virtual VCProjectWriter *createProjectWriter(); virtual bool doDepends() const { return false; } //never necesary virtual void processSources() { filterIncludedFiles("SOURCES"); filterIncludedFiles("GENERATED_SOURCES"); } - virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &); - inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out) - { return MakefileGenerator::replaceExtraCompilerVariables(val, in, out); } + using MakefileGenerator::ReplaceFor; + virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor); + inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out, ReplaceFor forShell) + { return MakefileGenerator::replaceExtraCompilerVariables(val, in, out, forShell); } virtual bool supportsMetaBuild() { return true; } virtual bool supportsMergedBuilds() { return true; } virtual bool mergeBuildProject(MakefileGenerator *other); virtual bool openOutput(QFile &file, const QString &build) const; - virtual void outputVariables(); - QString fixFilename(QString ofile) const; - void initOld(); virtual void initProject(); void initConfiguration(); void initCompilerTool(); @@ -111,9 +108,9 @@ protected: void initFormFiles(); void initResourceFiles(); void initDeploymentFiles(); + void initDistributionFiles(); void initLexYaccFiles(); void initExtraCompilerOutputs(); - void initWMAppManifest(); void writeSubDirs(QTextStream &t); // Called from VCXProj backend QUuid getProjectUUID(const QString &filename=QString()); // Called from VCXProj backend diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 97439115b6..5282989369 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/win32/msvc_vcxproj.h b/qmake/generators/win32/msvc_vcxproj.h index 4ff7403e13..0ffe5f3aff 100644 --- a/qmake/generators/win32/msvc_vcxproj.h +++ b/qmake/generators/win32/msvc_vcxproj.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 3a2e146a33..6ea129f82c 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -52,12 +52,12 @@ Win32MakefileGenerator::Win32MakefileGenerator() : MakefileGenerator() int Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem, const QString &ext) { - QString bd = Option::fixPathToLocalOS(d, true); + QString bd = Option::normalizePath(d); if(!exists(bd)) return -1; QMakeMetaInfo libinfo(project); - bool libInfoRead = libinfo.readLib(bd + Option::dir_sep + stem); + bool libInfoRead = libinfo.readLib(bd + '/' + stem); // If the library, for which we're trying to find the highest version // number, is a static library @@ -96,6 +96,16 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem return biggest; } +ProString Win32MakefileGenerator::fixLibFlag(const ProString &lib) +{ + if (lib.startsWith('/')) { + if (lib.startsWith("/LIBPATH:")) + return QStringLiteral("/LIBPATH:") + escapeFilePath(lib.mid(9)); + return lib; + } + return escapeFilePath(lib); +} + bool Win32MakefileGenerator::findLibraries() { @@ -104,26 +114,23 @@ Win32MakefileGenerator::findLibraries() for (int i = 0; lflags[i]; i++) { ProStringList &l = project->values(lflags[i]); for (ProStringList::Iterator it = l.begin(); it != l.end();) { - QChar quote; - bool modified_opt = false, remove = false; + bool remove = false; QString opt = (*it).trimmed().toQString(); - if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) { - quote = opt[0]; - opt = opt.mid(1, opt.length()-2); - } if(opt.startsWith("/LIBPATH:")) { - dirs.append(QMakeLocalFileName(opt.mid(9))); + QString libpath = opt.mid(9); + QMakeLocalFileName l(libpath); + if (!dirs.contains(l)) { + dirs.append(l); + (*it) = "/LIBPATH:" + l.real(); + } else { + remove = true; + } } else if(opt.startsWith("-L") || opt.startsWith("/L")) { QString libpath = Option::fixPathToTargetOS(opt.mid(2), false, false); QMakeLocalFileName l(libpath); if(!dirs.contains(l)) { dirs.append(l); - modified_opt = true; - if (!quote.isNull()) { - libpath = quote + libpath + quote; - quote = QChar(); - } - (*it) = "/LIBPATH:" + libpath; + (*it) = "/LIBPATH:" + l.real(); } else { remove = true; } @@ -139,24 +146,19 @@ Win32MakefileGenerator::findLibraries() extension += QString::number(ver); extension += suffix; extension += ".lib"; - if(QMakeMetaInfo::libExists((*it).local() + Option::dir_sep + lib) || - exists((*it).local() + Option::dir_sep + lib + extension)) { + if (QMakeMetaInfo::libExists((*it).local() + '/' + lib) + || exists((*it).local() + '/' + lib + extension)) { out = (*it).real() + Option::dir_sep + lib + extension; - if (out.contains(QLatin1Char(' '))) { - out.prepend(QLatin1Char('\"')); - out.append(QLatin1Char('\"')); - } break; } } } if(out.isEmpty()) out = lib + ".lib"; - modified_opt = true; (*it) = out; - } else if(!exists(Option::fixPathToLocalOS(opt))) { + } else if (!exists(Option::normalizePath(opt))) { QList<QMakeLocalFileName> lib_dirs; - QString file = opt; + QString file = Option::fixPathToTargetOS(opt); int slsh = file.lastIndexOf(Option::dir_sep); if(slsh != -1) { lib_dirs.append(QMakeLocalFileName(file.left(slsh+1))); @@ -167,7 +169,7 @@ Win32MakefileGenerator::findLibraries() if(file.endsWith(".lib")) { file = file.left(file.length() - 4); if(!file.at(file.length()-1).isNumber()) { - ProString suffix = project->first(ProKey("QMAKE_" + file.section(Option::dir_sep, -1).toUpper() + "_SUFFIX")); + ProString suffix = project->first(ProKey("QMAKE_" + file.toUpper() + "_SUFFIX")); for(QList<QMakeLocalFileName>::Iterator dep_it = lib_dirs.begin(); dep_it != lib_dirs.end(); ++dep_it) { QString lib_tmpl(file + "%1" + suffix + ".lib"); int ver = findHighestVersion((*dep_it).local(), file); @@ -182,7 +184,6 @@ Win32MakefileGenerator::findLibraries() dir += Option::dir_sep; lib_tmpl.prepend(dir); } - modified_opt = true; (*it) = lib_tmpl; break; } @@ -193,8 +194,6 @@ Win32MakefileGenerator::findLibraries() if(remove) { it = l.erase(it); } else { - if(!quote.isNull() && modified_opt) - (*it) = quote + (*it) + quote; ++it; } } @@ -212,8 +211,6 @@ Win32MakefileGenerator::processPrlFiles() ProStringList &l = project->values(lflags[i]); for (int lit = 0; lit < l.size(); ++lit) { QString opt = l.at(lit).trimmed().toQString(); - if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) - opt = opt.mid(1, opt.length()-2); if (opt.startsWith(libArg)) { QMakeLocalFileName l(opt.mid(libArg.length())); if (!libdirs.contains(l)) @@ -226,21 +223,15 @@ Win32MakefileGenerator::processPrlFiles() else tmp = opt; for(QList<QMakeLocalFileName>::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) { - QString prl = (*it).local() + Option::dir_sep + tmp; + QString prl = (*it).local() + '/' + tmp; if (processPrlFile(prl)) break; } } } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); - for (int prl = 0; prl < prl_libs.size(); ++prl) { - ProString arg = prl_libs.at(prl); - if (arg.startsWith(libArg)) - arg = arg.left(libArg.length()) + escapeFilePath(arg.mid(libArg.length()).toQString()); - else if (!arg.startsWith('/')) - arg = escapeFilePath(arg.toQString()); - l.insert(lit + prl + 1, arg); - } + for (int prl = 0; prl < prl_libs.size(); ++prl) + l.insert(lit + prl + 1, prl_libs.at(prl)); prl_libs.clear(); } @@ -287,43 +278,24 @@ void Win32MakefileGenerator::processVars() if (!project->isActiveConfig("skip_target_version_ext") && project->values("TARGET_VERSION_EXT").isEmpty() && !project->values("VER_MAJ").isEmpty()) - project->values("TARGET_VERSION_EXT").append(project->values("VER_MAJ").first()); - - if(project->isEmpty("QMAKE_COPY_FILE")) - 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")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); + project->values("TARGET_VERSION_EXT").append(project->first("VER_MAJ")); fixTargetExt(); processRcFileVar(); - ProStringList &incDir = project->values("INCLUDEPATH"); - for (ProStringList::Iterator incDir_it = incDir.begin(); incDir_it != incDir.end(); ++incDir_it) - if (!(*incDir_it).isEmpty()) - (*incDir_it) = Option::fixPathToTargetOS((*incDir_it).toQString(), false, false); - ProString libArg = project->first("QMAKE_L_FLAG"); ProStringList libs; ProStringList &libDir = project->values("QMAKE_LIBDIR"); for (ProStringList::Iterator libDir_it = libDir.begin(); libDir_it != libDir.end(); ++libDir_it) { QString lib = (*libDir_it).toQString(); if (!lib.isEmpty()) { - lib.remove('"'); if (lib.endsWith('\\')) lib.chop(1); - libs << libArg + escapeFilePath(Option::fixPathToTargetOS(lib, false, false)); + libs << libArg + Option::fixPathToTargetOS(lib, false, false); } } - project->values("QMAKE_LIBS") += libs + escapeFilePaths(project->values("LIBS")); - project->values("QMAKE_LIBS_PRIVATE") += escapeFilePaths(project->values("LIBS_PRIVATE")); + project->values("QMAKE_LIBS") += libs + project->values("LIBS"); + project->values("QMAKE_LIBS_PRIVATE") += project->values("LIBS_PRIVATE"); if (project->values("TEMPLATE").contains("app")) { project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_APP"); @@ -368,7 +340,8 @@ void Win32MakefileGenerator::processRcFileVar() if (Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING) return; - if (((!project->values("VERSION").isEmpty() || !project->values("RC_ICONS").isEmpty()) + const QString manifestFile = getManifestFileForRcFile(); + if (((!project->values("VERSION").isEmpty() || !project->values("RC_ICONS").isEmpty() || !manifestFile.isEmpty()) && project->values("RC_FILE").isEmpty() && project->values("RES_FILE").isEmpty() && !project->isActiveConfig("no_generated_target_info") @@ -405,14 +378,14 @@ void Win32MakefileGenerator::processRcFileVar() else productName = project->first("TARGET").toQString(); - QString originalName = project->values("TARGET").first() + project->values("TARGET_EXT").first(); + QString originalName = project->first("TARGET") + project->first("TARGET_EXT"); int rcLang = project->intValue("RC_LANG", 1033); // default: English(USA) int rcCodePage = project->intValue("RC_CODEPAGE", 1200); // default: Unicode ts << "# if defined(UNDER_CE)\n"; ts << "# include <winbase.h>\n"; ts << "# else\n"; - ts << "# include <winver.h>\n"; + ts << "# include <windows.h>\n"; ts << "# endif\n"; ts << endl; if (!rcIcons.isEmpty()) { @@ -420,6 +393,14 @@ void Win32MakefileGenerator::processRcFileVar() ts << QString("IDI_ICON%1\tICON\tDISCARDABLE\t%2").arg(i + 1).arg(cQuoted(rcIcons[i])) << endl; ts << endl; } + if (!manifestFile.isEmpty()) { + QString manifestResourceId; + if (project->first("TEMPLATE") == "lib") + manifestResourceId = QStringLiteral("ISOLATIONAWARE_MANIFEST_RESOURCE_ID"); + else + manifestResourceId = QStringLiteral("CREATEPROCESS_MANIFEST_RESOURCE_ID"); + ts << manifestResourceId << " RT_MANIFEST \"" << manifestFile << "\"\n"; + } ts << "VS_VERSION_INFO VERSIONINFO\n"; ts << "\tFILEVERSION " << QString(versionString).replace(".", ",") << endl; ts << "\tPRODUCTVERSION " << QString(versionString).replace(".", ",") << endl; @@ -464,9 +445,9 @@ void Win32MakefileGenerator::processRcFileVar() ts.flush(); - QString rcFilename = project->values("OUT_PWD").first() + QString rcFilename = project->first("OUT_PWD") + "/" - + project->values("TARGET").first() + + project->first("TARGET") + "_resource" + ".rc"; QFile rcFile(QDir::cleanPath(rcFilename)); @@ -511,17 +492,17 @@ void Win32MakefileGenerator::processRcFileVar() resFile.replace(".rc", Option::res_ext); project->values("RES_FILE").prepend(fileInfo(resFile).fileName()); - if (!project->values("OBJECTS_DIR").isEmpty()) { - QString resDestDir; - if (project->isActiveConfig("staticlib")) - resDestDir = fileInfo(project->first("DESTDIR").toQString()).absoluteFilePath(); - else - resDestDir = project->first("OBJECTS_DIR").toQString(); + QString resDestDir; + if (project->isActiveConfig("staticlib")) + resDestDir = project->first("DESTDIR").toQString(); + else + resDestDir = project->first("OBJECTS_DIR").toQString(); + if (!resDestDir.isEmpty()) { resDestDir.append(Option::dir_sep); project->values("RES_FILE").first().prepend(resDestDir); } project->values("RES_FILE").first() = Option::fixPathToTargetOS( - project->values("RES_FILE").first().toQString(), false, false); + project->first("RES_FILE").toQString(), false); project->values("POST_TARGETDEPS") += project->values("RES_FILE"); project->values("CLEAN_FILES") += project->values("RES_FILE"); } @@ -529,7 +510,7 @@ void Win32MakefileGenerator::processRcFileVar() void Win32MakefileGenerator::writeCleanParts(QTextStream &t) { - t << "clean: compiler_clean " << var("CLEAN_DEPS"); + t << "clean: compiler_clean " << depVar("CLEAN_DEPS"); { const char *clean_targets[] = { "OBJECTS", "QMAKE_CLEAN", "CLEAN_FILES", 0 }; for(int i = 0; clean_targets[i]; ++i) { @@ -558,7 +539,7 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t) } t << endl << endl; - t << "distclean: clean " << var("DISTCLEAN_DEPS"); + t << "distclean: clean " << depVar("DISTCLEAN_DEPS"); { const char *clean_targets[] = { "QMAKE_DISTCLEAN", 0 }; for(int i = 0; clean_targets[i]; ++i) { @@ -587,9 +568,9 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t) } t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET)\n"; { - QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); + QString ofile = fileFixify(Option::output.fileName()); if(!ofile.isEmpty()) - t << "\t-$(DEL_FILE) " << ofile << endl; + t << "\t-$(DEL_FILE) " << escapeFilePath(ofile) << endl; } t << endl; } @@ -602,9 +583,8 @@ void Win32MakefileGenerator::writeIncPart(QTextStream &t) for(int i = 0; i < incs.size(); ++i) { QString inc = incs.at(i).toQString(); inc.replace(QRegExp("\\\\$"), ""); - inc.replace(QRegExp("\""), ""); if(!inc.isEmpty()) - t << "-I\"" << inc << "\" "; + t << "-I" << escapeFilePath(inc) << ' '; } t << endl; } @@ -624,13 +604,13 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) writeLibsPart(t); t << "QMAKE = " << var("QMAKE_QMAKE") << endl; - t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : - Option::fixPathToTargetOS(var("QMAKE_IDC"), false)) << endl; - t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : - Option::fixPathToTargetOS(var("QMAKE_IDL"), false)) << endl; + t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : var("QMAKE_IDC")) + << endl; + t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : var("QMAKE_IDL")) + << endl; t << "ZIP = " << var("QMAKE_ZIP") << endl; - t << "DEF_FILE = " << varList("DEF_FILE") << endl; - t << "RES_FILE = " << varList("RES_FILE") << endl; // Not on mingw, can't see why not though... + t << "DEF_FILE = " << fileVar("DEF_FILE") << endl; + t << "RES_FILE = " << fileVar("RES_FILE") << endl; // Not on mingw, can't see why not though... t << "COPY = " << var("QMAKE_COPY") << endl; t << "SED = " << var("QMAKE_STREAM_EDITOR") << endl; t << "COPY_FILE = " << var("QMAKE_COPY_FILE") << endl; @@ -647,7 +627,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) t << "####### Output directory\n\n"; if(!project->values("OBJECTS_DIR").isEmpty()) - t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl; + t << "OBJECTS_DIR = " << escapeFilePath(var("OBJECTS_DIR").remove(QRegExp("\\\\$"))) << endl; else t << "OBJECTS_DIR = . \n"; t << endl; @@ -662,7 +642,6 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) if (!destDir.isEmpty() && (orgDestDir.endsWith('/') || orgDestDir.endsWith(Option::dir_sep))) destDir += Option::dir_sep; QString target = QString(project->first("TARGET")+project->first("TARGET_EXT")); - target.remove("\""); project->values("DEST_TARGET").prepend(destDir + target); writeObjectsPart(t); @@ -670,15 +649,14 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) writeExtraCompilerVariables(t); writeExtraVariables(t); - t << "DIST = " << varList("DISTFILES") << " " - << varList("HEADERS") << " " - << varList("SOURCES") << endl; - t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; + t << "DIST = " << fileVarList("DISTFILES") << ' ' + << fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << endl; + t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl; // The comment is important to maintain variable compatibility with Unix // Makefiles, while not interpreting a trailing-slash as a linebreak t << "DESTDIR = " << escapeFilePath(destDir) << " #avoid trailing-slash linebreak\n"; t << "TARGET = " << escapeFilePath(target) << endl; - t << "DESTDIR_TARGET = " << escapeFilePath(var("DEST_TARGET")) << endl; + t << "DESTDIR_TARGET = " << fileVar("DEST_TARGET") << endl; t << endl; t << "####### Implicit rules\n\n"; @@ -690,8 +668,8 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) if(project->isActiveConfig("shared") && !project->values("DLLDESTDIR").isEmpty()) { const ProStringList &dlldirs = project->values("DLLDESTDIR"); for (ProStringList::ConstIterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir) { - t << "\t-$(COPY_FILE) \"$(DESTDIR_TARGET)\" " - << Option::fixPathToTargetOS((*dlldir).toQString(), false) << endl; + t << "\t-$(COPY_FILE) $(DESTDIR_TARGET) " + << escapeFilePath(Option::fixPathToTargetOS((*dlldir).toQString(), false)) << endl; } } t << endl; @@ -715,13 +693,13 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) } t << "dist:\n\t" << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip $(SOURCES) $(DIST) " - << dist_files.join(' ') << " " << var("TRANSLATIONS") << " "; + << escapeFilePaths(dist_files).join(' ') << ' ' << fileVar("TRANSLATIONS") << ' '; if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) { const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { const ProStringList &inputs = project->values(ProKey(*it + ".input")); for (ProStringList::ConstIterator input = inputs.begin(); input != inputs.end(); ++input) - t << (*input) << " "; + t << escapeFilePath(*input) << ' '; } } t << endl << endl; @@ -740,12 +718,14 @@ void Win32MakefileGenerator::writeLibsPart(QTextStream &t) } else { t << "LINKER = " << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; - t << "LIBS = " << var("QMAKE_LIBS") << " " << var("QMAKE_LIBS_PRIVATE") << endl; + t << "LIBS = " << fixLibFlags("QMAKE_LIBS").join(' ') << ' ' + << fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl; } } void Win32MakefileGenerator::writeObjectsPart(QTextStream &t) { + // Used in both deps and commands. t << "OBJECTS = " << valList(escapeDependencyPaths(project->values("OBJECTS"))) << endl; } @@ -787,9 +767,10 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) incPathStr += escapeFilePath(path); } - t << res_file << ": " << rc_file << "\n\t" + t << escapeDependencyPath(res_file) << ": " << escapeDependencyPath(rc_file) << "\n\t" << var("QMAKE_RC") << (project->isActiveConfig("debug") ? " -D_DEBUG" : "") - << " $(DEFINES)" << incPathStr << " -fo " << res_file << " " << rc_file; + << " $(DEFINES)" << incPathStr << " -fo " << escapeFilePath(res_file) + << ' ' << escapeFilePath(rc_file); t << endl << endl; } } @@ -809,8 +790,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) const QString root = "$(INSTALL_ROOT)"; ProStringList &uninst = project->values(ProKey(t + ".uninstall")); QString ret; - QString targetdir = Option::fixPathToTargetOS(project->first(ProKey(t + ".path")).toQString(), false); - targetdir = fileFixify(targetdir, FileFixifyAbsolute); + QString targetdir = fileFixify(project->first(ProKey(t + ".path")).toQString(), FileFixifyAbsolute); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; @@ -825,7 +805,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) ret += installMetaFile(ProKey("QMAKE_PRL_INSTALL_REPLACE"), project->first("QMAKE_INTERNAL_PRL_FILE").toQString(), dst_prl); if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_prl + "\""); + uninst.append("-$(DEL_FILE) " + escapeFilePath(dst_prl)); } if(project->isActiveConfig("create_pc")) { QString dst_pc = pkgConfigFileName(false); @@ -842,32 +822,35 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) ret += installMetaFile(ProKey("QMAKE_PKGCONFIG_INSTALL_REPLACE"), pkgConfigFileName(true), dst_pc); if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_pc + "\""); + uninst.append("-$(DEL_FILE) " + escapeFilePath(dst_pc)); } } if(project->isActiveConfig("shared") && !project->isActiveConfig("plugin")) { QString lib_target = getLibTarget(); - lib_target.remove('"'); - QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + lib_target; - QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + lib_target, FileFixifyAbsolute)); + QString src_targ = escapeFilePath( + (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + + lib_target); + QString dst_targ = escapeFilePath( + filePrefixRoot(root, fileFixify(targetdir + lib_target, FileFixifyAbsolute))); if(!ret.isEmpty()) ret += "\n\t"; - ret += QString("-$(INSTALL_FILE)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; + ret += QString("-$(INSTALL_FILE) ") + src_targ + ' ' + dst_targ; if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + uninst.append("-$(DEL_FILE) " + dst_targ); } } if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { QString src_targ = "$(DESTDIR_TARGET)"; - QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + "$(TARGET)", FileFixifyAbsolute)); + QString dst_targ = escapeFilePath( + filePrefixRoot(root, fileFixify(targetdir + "$(TARGET)", FileFixifyAbsolute))); if(!ret.isEmpty()) ret += "\n\t"; - ret += QString("-$(INSTALL_FILE)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; + ret += QString("-$(INSTALL_FILE) ") + src_targ + ' ' + dst_targ; if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + uninst.append("-$(DEL_FILE) " + dst_targ); } return ret; } @@ -876,7 +859,6 @@ QString Win32MakefileGenerator::escapeFilePath(const QString &path) const { QString ret = path; if(!ret.isEmpty()) { - ret = unescapeFilePath(ret); if (ret.contains(' ') || ret.contains('\t')) ret = "\"" + ret + "\""; debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); @@ -894,4 +876,9 @@ QString Win32MakefileGenerator::cQuoted(const QString &str) return ret; } +QString Win32MakefileGenerator::getManifestFileForRcFile() const +{ + return QString(); +} + QT_END_NAMESPACE diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 3016bad5b4..ea763c3175 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -60,12 +60,15 @@ protected: int findHighestVersion(const QString &dir, const QString &stem, const QString &ext = QLatin1String("lib")); virtual bool findLibraries(); + virtual ProString fixLibFlag(const ProString &lib); + virtual void processPrlFiles(); void processVars(); void fixTargetExt(); void processRcFileVar(); virtual QString getLibTarget(); static QString cQuoted(const QString &str); + virtual QString getManifestFileForRcFile() const; }; inline Win32MakefileGenerator::~Win32MakefileGenerator() diff --git a/qmake/generators/xmloutput.cpp b/qmake/generators/xmloutput.cpp index 9cc8cdca0d..4f2e7fee69 100644 --- a/qmake/generators/xmloutput.cpp +++ b/qmake/generators/xmloutput.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/generators/xmloutput.h b/qmake/generators/xmloutput.h index 5b66d63043..2adb0e2d2e 100644 --- a/qmake/generators/xmloutput.h +++ b/qmake/generators/xmloutput.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp index 8dd88bf9a5..04be215246 100644 --- a/qmake/library/ioutils.cpp +++ b/qmake/library/ioutils.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -100,11 +100,18 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName) } inline static +bool isSpecialChar(ushort c, const uchar (&iqm)[16]) +{ + if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)))) + return true; + return false; +} + +inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16]) { for (int x = arg.length() - 1; x >= 0; --x) { - ushort c = arg.unicode()[x].unicode(); - if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)))) + if (isSpecialChar(arg.unicode()[x].unicode(), iqm)) return true; } return false; @@ -119,7 +126,7 @@ QString IoUtils::shellQuoteUnix(const QString &arg) }; // 0-32 \'"$`<>|;&(){}*?#!~[] if (!arg.length()) - return QString::fromLatin1("\"\""); + return QString::fromLatin1("''"); QString ret(arg); if (hasSpecialChars(ret, iqm)) { @@ -140,23 +147,38 @@ QString IoUtils::shellQuoteWin(const QString &arg) 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10 }; + // Shell meta chars that need escaping. + static const uchar ism[] = { + 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10 + }; // &()<>^| if (!arg.length()) return QString::fromLatin1("\"\""); QString ret(arg); if (hasSpecialChars(ret, iqm)) { - // Quotes are escaped and their preceding backslashes are doubled. - // It's impossible to escape anything inside a quoted string on cmd - // level, so the outer quoting must be "suspended". - ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\"")); - // The argument must not end with a \ since this would be interpreted - // as escaping the quote -- rather put the \ behind the quote: e.g. - // rather use "foo"\ than "foo\" - int i = ret.length(); - while (i > 0 && ret.at(i - 1) == QLatin1Char('\\')) - --i; - ret.insert(i, QLatin1Char('"')); + // The process-level standard quoting allows escaping quotes with backslashes (note + // that backslashes don't escape themselves, unless they are followed by a quote). + // Consequently, quotes are escaped and their preceding backslashes are doubled. + ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\"")); + // Trailing backslashes must be doubled as well, as they are followed by a quote. + ret.replace(QRegExp(QLatin1String("(\\\\+)$")), QLatin1String("\\1\\1")); + // However, the shell also interprets the command, and no backslash-escaping exists + // there - a quote always toggles the quoting state, but is nonetheless passed down + // to the called process verbatim. In the unquoted state, the circumflex escapes + // meta chars (including itself and quotes), and is removed from the command. + bool quoted = true; + for (int i = 0; i < ret.length(); i++) { + QChar c = ret.unicode()[i]; + if (c.unicode() == '"') + quoted = !quoted; + else if (!quoted && isSpecialChar(c.unicode(), ism)) + ret.insert(i++, QLatin1Char('^')); + } + if (!quoted) + ret.append(QLatin1Char('^')); + ret.append(QLatin1Char('"')); ret.prepend(QLatin1Char('"')); } return ret; diff --git a/qmake/library/ioutils.h b/qmake/library/ioutils.h index ba6e2708cb..b726ce3e09 100644 --- a/qmake/library/ioutils.h +++ b/qmake/library/ioutils.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index 97cc590d84..e780259417 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -386,6 +386,20 @@ void ProStringList::removeAll(const char *str) remove(i); } +void ProStringList::removeEach(const ProStringList &value) +{ + foreach (const ProString &str, value) + if (!str.isEmpty()) + removeAll(str); +} + +void ProStringList::removeEmpty() +{ + for (int i = size(); --i >= 0;) + if (at(i).isEmpty()) + remove(i); +} + void ProStringList::removeDuplicates() { int n = size(); @@ -405,6 +419,13 @@ void ProStringList::removeDuplicates() erase(begin() + j, end()); } +void ProStringList::insertUnique(const ProStringList &value) +{ + foreach (const ProString &str, value) + if (!str.isEmpty() && !contains(str)) + append(str); +} + ProStringList::ProStringList(const QStringList &list) { reserve(list.size()); diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 28178ac9a6..d31367361d 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -138,6 +138,7 @@ public: int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize + uint hash() const { return m_hash; } static uint hash(const QChar *p, int n); ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); } @@ -239,9 +240,13 @@ public: QString join(const QString &sep) const; QString join(QChar sep) const; + void insertUnique(const ProStringList &value); + void removeAll(const ProString &str); void removeAll(const char *str); + void removeEach(const ProStringList &value); void removeAt(int idx) { remove(idx); } + void removeEmpty(); void removeDuplicates(); bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; diff --git a/qmake/library/qmake_global.h b/qmake/library/qmake_global.h index 3bb9d9955f..8f2eb5fd33 100644 --- a/qmake/library/qmake_global.h +++ b/qmake/library/qmake_global.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index b735822806..e384d26f4c 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -218,8 +218,8 @@ static QString windowsErrorCode() } #endif -static QString -quoteValue(const ProString &val) +QString +QMakeEvaluator::quoteValue(const ProString &val) { QString ret; ret.reserve(val.size()); @@ -1202,15 +1202,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( VisitReturn ret = ReturnFalse; ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep), m_current.pro->fileName(), m_current.line); - if (pro) { - if (m_cumulative || pro->isOk()) { - m_locationStack.push(m_current); - visitProBlock(pro, pro->tokPtr()); - ret = ReturnTrue; // This return value is not too useful, but that's qmake - m_current = m_locationStack.pop(); - } - pro->deref(); + if (m_cumulative || pro->isOk()) { + m_locationStack.push(m_current); + visitProBlock(pro, pro->tokPtr()); + ret = ReturnTrue; // This return value is not too useful, but that's qmake + m_current = m_locationStack.pop(); } + pro->deref(); return ret; } case T_IF: { @@ -1689,7 +1687,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (mode == CacheAdd) newval += diffval; else - removeEach(&newval, diffval); + newval.removeEach(diffval); } if (oldval != newval) { if (target != TargetStash || !m_stashfile.isEmpty()) { diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 9b5291a08e..5c9dc45f3a 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -58,6 +58,9 @@ #ifdef Q_OS_UNIX #include <unistd.h> #include <sys/utsname.h> +# ifdef Q_OS_BSD4 +# include <sys/sysctl.h> +# endif #else #include <windows.h> #endif @@ -70,6 +73,39 @@ QT_BEGIN_NAMESPACE #define fL1S(s) QString::fromLatin1(s) +// we can't use QThread in qmake +// this function is a merger of QThread::idealThreadCount from qthread_win.cpp and qthread_unix.cpp +static int idealThreadCount() +{ +#ifdef PROEVALUATOR_THREAD_SAFE + return QThread::idealThreadCount(); +#elif defined(Q_OS_WIN) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + // there are a couple more definitions in the Unix QThread::idealThreadCount, but + // we don't need them all here + int cores = 1; +# if defined(Q_OS_BSD4) + // FreeBSD, OpenBSD, NetBSD, BSD/OS, Mac OS X + size_t len = sizeof(cores); + int mib[2]; + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) { + perror("sysctl"); + } +# elif defined(_SC_NPROCESSORS_ONLN) + // the rest: Linux, Solaris, AIX, Tru64 + cores = (int)sysconf(_SC_NPROCESSORS_ONLN); + if (cores == -1) + return 1; +# endif + return cores; +#endif +} + QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _hostBuild) : root(_root), stash(_stash), hostBuild(_hostBuild) @@ -314,34 +350,6 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil return ret; } -static void zipEmpty(ProStringList *value) -{ - for (int i = value->size(); --i >= 0;) - if (value->at(i).isEmpty()) - value->remove(i); -} - -static void insertUnique(ProStringList *varlist, const ProStringList &value) -{ - foreach (const ProString &str, value) - if (!str.isEmpty() && !varlist->contains(str)) - varlist->append(str); -} - -static void removeAll(ProStringList *varlist, const ProString &value) -{ - for (int i = varlist->size(); --i >= 0; ) - if (varlist->at(i) == value) - varlist->remove(i); -} - -void QMakeEvaluator::removeEach(ProStringList *varlist, const ProStringList &value) -{ - foreach (const ProString &str, value) - if (!str.isEmpty()) - removeAll(varlist, str); -} - static void replaceInList(ProStringList *varlist, const QRegExp ®exp, const QString &replace, bool global, QString &tmp) { @@ -880,24 +888,24 @@ void QMakeEvaluator::visitProVariable( switch (tok) { default: // whatever - cannot happen case TokAssign: // = - zipEmpty(&varVal); + varVal.removeEmpty(); // FIXME: add check+warning about accidental value removal. // This may be a bit too noisy, though. m_valuemapStack.top()[varName] = varVal; debugMsg(2, "assigning"); break; case TokAppendUnique: // *= - insertUnique(&valuesRef(varName), varVal); + valuesRef(varName).insertUnique(varVal); debugMsg(2, "appending unique"); break; case TokAppend: // += - zipEmpty(&varVal); + varVal.removeEmpty(); valuesRef(varName) += varVal; debugMsg(2, "appending"); break; case TokRemove: // -= if (!m_cumulative) { - removeEach(&valuesRef(varName), varVal); + valuesRef(varName).removeEach(varVal); } else { // We are stingy with our values. } @@ -998,6 +1006,7 @@ void QMakeEvaluator::loadDefaults() vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation); if (!m_option->qmake_args.isEmpty()) vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args); + vars[ProKey("QMAKE_HOST.cpu_count")] = ProString(QString::number(idealThreadCount())); #if defined(Q_OS_WIN32) vars[ProKey("QMAKE_HOST.os")] << ProString("Windows"); @@ -1270,14 +1279,13 @@ void QMakeEvaluator::setupProject() void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where) { if (!cmds.isEmpty()) { - if (ProFile *pro = m_parser->parsedProBlock(cmds, where, -1)) { - if (pro->isOk()) { - m_locationStack.push(m_current); - visitProBlock(pro, pro->tokPtr()); - m_current = m_locationStack.pop(); - } - pro->deref(); + ProFile *pro = m_parser->parsedProBlock(cmds, where, -1); + if (pro->isOk()) { + m_locationStack.push(m_current); + visitProBlock(pro, pro->tokPtr()); + m_current = m_locationStack.pop(); } + pro->deref(); } } @@ -1757,14 +1765,12 @@ bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &whe { bool ret = false; ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar); - if (pro) { - if (pro->isOk()) { - m_locationStack.push(m_current); - ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue; - m_current = m_locationStack.pop(); - } - pro->deref(); + if (pro->isOk()) { + m_locationStack.push(m_current); + ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue; + m_current = m_locationStack.pop(); } + pro->deref(); return ret; } diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 73fd5bb82f..4f2acf25ee 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -243,8 +243,6 @@ public: #endif QByteArray getCommandOutput(const QString &args) const; - static void removeEach(ProStringList *varlist, const ProStringList &value); - QMakeEvaluator *m_caller; #ifdef PROEVALUATOR_CUMULATIVE bool m_cumulative; @@ -254,6 +252,8 @@ public: enum { m_skipLevel = 0 }; #endif + static QString quoteValue(const ProString &val); + #ifdef PROEVALUATOR_DEBUG void debugMsgInternal(int level, const char *fmt, ...) const; void traceMsgInternal(const char *fmt, ...) const; diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h index dd63bcea02..e000fc9cf5 100644 --- a/qmake/library/qmakeevaluator_p.h +++ b/qmake/library/qmakeevaluator_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp index aeb8a6c803..55ce404410 100644 --- a/qmake/library/qmakeglobals.cpp +++ b/qmake/library/qmakeglobals.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h index 6950d32807..7c77450523 100644 --- a/qmake/library/qmakeglobals.h +++ b/qmake/library/qmakeglobals.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 3065d4dd5a..3fd7957bc0 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -209,10 +209,7 @@ ProFile *QMakeParser::parsedProBlock( const QString &contents, const QString &name, int line, SubGrammar grammar) { ProFile *pro = new ProFile(name); - if (!read(pro, contents, line, grammar)) { - delete pro; - pro = 0; - } + read(pro, contents, line, grammar); return pro; } @@ -232,7 +229,8 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags) fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr)); return false; } - return read(pro, content, 1, FullGrammar); + read(pro, content, 1, FullGrammar); + return true; } void QMakeParser::putTok(ushort *&tokPtr, ushort tok) @@ -272,7 +270,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len) buf[-2] = (ushort)(hash >> 16); } -bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar) +void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar) { m_proFile = pro; m_lineNo = line; @@ -322,7 +320,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra m_canElse = false; freshLine: m_state = StNew; - m_invert = false; + m_invert = 0; m_operator = NoOperator; m_markLine = m_lineNo; m_inError = false; @@ -579,7 +577,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra parseError(fL1S("Missing %1 terminator [found %2]") .arg(QChar(term)) .arg(c ? QString(c) : QString::fromLatin1("end-of-line"))); - pro->setOk(false); m_inError = true; // Just parse on, as if there was a terminator ... } else { @@ -606,7 +603,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra quote = 0; goto nextChr; } else if (c == '!' && ptr == xprPtr && context == CtxTest) { - m_invert ^= true; + m_invert++; goto nextChr; } } else if (c == '\'' || c == '"') { @@ -663,20 +660,20 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra parseError(fL1S("Extra characters after test expression.")); else parseError(fL1S("Opening parenthesis without prior test name.")); - pro->setOk(false); ptr = buf; // Put empty function name } *ptr++ = TokTestCall; term = ':'; goto funcCall; } else if (c == '!' && ptr == xprPtr) { - m_invert ^= true; + m_invert++; goto nextChr; } else if (c == ':') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("in front of AND operator"); if (m_state == StNew) - parseError(fL1S("And operator without prior condition.")); + parseError(fL1S("AND operator without prior condition.")); else m_operator = AndOperator; nextItem: @@ -685,26 +682,33 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } else if (c == '|') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("in front of OR operator"); if (m_state != StCond) - parseError(fL1S("Or operator without prior condition.")); + parseError(fL1S("OR operator without prior condition.")); else m_operator = OrOperator; goto nextItem; } else if (c == '{') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + if (m_operator == AndOperator) { + languageWarning(fL1S("Excess colon in front of opening brace.")); + m_operator = NoOperator; + } + failOperator("in front of opening brace"); flushCond(tokPtr); + m_state = StNew; // Reset possible StCtrl, so colons get rejected. ++m_blockstack.top().braceLevel; - if (grammar == TestGrammar) { + if (grammar == TestGrammar) parseError(fL1S("Opening scope not permitted in this context.")); - pro->setOk(false); - } goto nextItem; } else if (c == '}') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); - flushScopes(tokPtr); + m_state = StNew; // De-facto newline closeScope: + flushScopes(tokPtr); + failOperator("in front of closing brace"); if (!m_blockstack.top().braceLevel) { parseError(fL1S("Excess closing brace.")); } else if (!--m_blockstack.top().braceLevel @@ -736,13 +740,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra doOp: FLUSH_LHS_LITERAL(); flushCond(tokPtr); + acceptColon("in front of assignment"); putLineMarker(tokPtr); if (grammar == TestGrammar) { parseError(fL1S("Assignment not permitted in this context.")); - pro->setOk(false); } else if (wordCount != 1) { parseError(fL1S("Assignment needs exactly one word on the left hand side.")); - pro->setOk(false); // Put empty variable name. } else { putBlock(tokPtr, buf, ptr - buf); @@ -811,7 +814,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } else if (context == CtxPureValue) { putTok(tokPtr, TokValueTerminator); } else { - bogusTest(tokPtr); + bogusTest(tokPtr, QString()); } } else if (context == CtxValue) { FLUSH_VALUE_LIST(); @@ -822,6 +825,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra putTok(tokPtr, TokValueTerminator); } else { finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("at end of line"); } if (!cur) break; @@ -837,15 +841,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } flushScopes(tokPtr); - if (m_blockstack.size() > 1) { + if (m_blockstack.size() > 1 || m_blockstack.top().braceLevel) parseError(fL1S("Missing closing brace(s).")); - pro->setOk(false); - } while (m_blockstack.size()) leaveScope(tokPtr); tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays *pro->itemsRef() = tokBuff; - return true; #undef FLUSH_VALUE_LIST #undef FLUSH_LITERAL @@ -918,39 +919,90 @@ void QMakeParser::flushCond(ushort *&tokPtr) } } -void QMakeParser::finalizeTest(ushort *&tokPtr) +void QMakeParser::warnOperator(const char *msg) { - flushScopes(tokPtr); - putLineMarker(tokPtr); - if (m_operator != NoOperator) { - putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr); + if (m_invert) { + languageWarning(fL1S("Stray NOT operator %1.").arg(fL1S(msg))); + m_invert = 0; + } + if (m_operator == AndOperator) { + languageWarning(fL1S("Stray AND operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + } else if (m_operator == OrOperator) { + languageWarning(fL1S("Stray OR operator %1.").arg(fL1S(msg))); m_operator = NoOperator; } +} + +bool QMakeParser::failOperator(const char *msg) +{ + bool fail = false; if (m_invert) { - putTok(tokPtr, TokNot); - m_invert = false; + parseError(fL1S("Unexpected NOT operator %1.").arg(fL1S(msg))); + m_invert = 0; + fail = true; + } + if (m_operator == AndOperator) { + parseError(fL1S("Unexpected AND operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + fail = true; + } else if (m_operator == OrOperator) { + parseError(fL1S("Unexpected OR operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + fail = true; + } + return fail; +} + +bool QMakeParser::acceptColon(const char *msg) +{ + if (m_operator == AndOperator) + m_operator = NoOperator; + return !failOperator(msg); +} + +void QMakeParser::putOperator(ushort *&tokPtr) +{ + if (m_operator== AndOperator) { + // A colon must be used after else and for() if no brace is used, + // but in this case it is obviously not a binary operator. + if (m_state == StCond) + putTok(tokPtr, TokAnd); + m_operator = NoOperator; + } else if (m_operator == OrOperator) { + putTok(tokPtr, TokOr); + m_operator = NoOperator; } +} + +void QMakeParser::finalizeTest(ushort *&tokPtr) +{ + flushScopes(tokPtr); + putLineMarker(tokPtr); + putOperator(tokPtr); + if (m_invert & 1) + putTok(tokPtr, TokNot); + m_invert = 0; m_state = StCond; m_canElse = true; } -void QMakeParser::bogusTest(ushort *&tokPtr) +void QMakeParser::bogusTest(ushort *&tokPtr, const QString &msg) { + if (!msg.isEmpty()) + parseError(msg); flushScopes(tokPtr); m_operator = NoOperator; - m_invert = false; + m_invert = 0; m_state = StCond; m_canElse = true; - m_proFile->setOk(false); } void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount) { if (wordCount != 1) { - if (wordCount) { - parseError(fL1S("Extra characters after test expression.")); - bogusTest(tokPtr); - } + if (wordCount) + bogusTest(tokPtr, fL1S("Extra characters after test expression.")); return; } @@ -961,10 +1013,8 @@ void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wor if (uce == ptr) { m_tmp.setRawData((QChar *)uc + 4, nlen); if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) { - if (m_invert || m_operator != NoOperator) { - parseError(fL1S("Unexpected operator in front of else.")); + if (failOperator("in front of else")) return; - } BlockScope &top = m_blockstack.top(); if (m_canElse && (!top.special || top.braceLevel)) { // A list of tests (the last one likely with side effects), @@ -1009,18 +1059,18 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg const QString *defName; ushort defType; if (m_tmp == statics.strfor) { - if (m_invert || m_operator == OrOperator) { - // '|' could actually work reasonably, but qmake does nonsense here. - parseError(fL1S("Unexpected operator in front of for().")); - bogusTest(tokPtr); + if (!acceptColon("in front of for()")) { + bogusTest(tokPtr, QString()); return; } flushCond(tokPtr); putLineMarker(tokPtr); + --ptr; + Q_ASSERT(*ptr == TokFuncTerminator); if (*uce == (TokLiteral|TokNewStr)) { nlen = uce[1]; uc = uce + 2 + nlen; - if (*uc == TokFuncTerminator) { + if (uc == ptr) { // for(literal) (only "ever" would be legal if qmake was sane) putTok(tokPtr, TokForLoop); putHashStr(tokPtr, (ushort *)0, (uint)0); @@ -1061,8 +1111,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg defType = TokTestDef; deffunc: if (m_invert) { - parseError(fL1S("Unexpected operator in front of function definition.")); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of function definition.")); return; } flushScopes(tokPtr); @@ -1070,10 +1119,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg if (*uce == (TokLiteral|TokNewStr)) { uint nlen = uce[1]; if (uce[nlen + 2] == TokFuncTerminator) { - if (m_operator != NoOperator) { - putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr); - m_operator = NoOperator; - } + putOperator(tokPtr); putTok(tokPtr, defType); putHashStr(tokPtr, uce + 2, nlen); enterScope(tokPtr, true, StCtrl); @@ -1086,14 +1132,12 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg } else if (m_tmp == statics.strreturn) { if (m_blockstack.top().nest & NestFunction) { if (argc > 1) { - parseError(fL1S("return() requires zero or one argument.")); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("return() requires zero or one argument.")); return; } } else { if (*uce != TokFuncTerminator) { - parseError(fL1S("Top-level return() requires zero arguments.")); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("Top-level return() requires zero arguments.")); return; } } @@ -1106,19 +1150,16 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg defType = TokBreak; ctrlstm: if (*uce != TokFuncTerminator) { - parseError(fL1S("%1() requires zero arguments.").arg(m_tmp)); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp)); return; } if (!(m_blockstack.top().nest & NestLoop)) { - parseError(fL1S("Unexpected %1().").arg(m_tmp)); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp)); return; } ctrlstm2: if (m_invert) { - parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp)); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp)); return; } finalizeTest(tokPtr); @@ -1128,8 +1169,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg } else if (m_tmp == statics.stroption) { if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1 || m_invert || m_operator != NoOperator) { - parseError(fL1S("option() must appear outside any control structures.")); - bogusTest(tokPtr); + bogusTest(tokPtr, fL1S("option() must appear outside any control structures.")); return; } if (*uce == (TokLiteral|TokNewStr)) { @@ -1210,4 +1250,258 @@ void QMakeParser::message(int type, const QString &msg) const m_handler->message(type, msg, m_proFile->fileName(), m_lineNo); } +#ifdef PROPARSER_DEBUG + +#define BOUNDS_CHECK(need) \ + do { \ + int have = limit - offset; \ + if (have < (int)need) { \ + *outStr += fL1S("<out of bounds (need %1, got %2)>").arg(need).arg(have); \ + return false; \ + } \ + } while (0) + +static bool getRawUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr) +{ + BOUNDS_CHECK(1); + uint val = tokens[offset++]; + *outVal = val; + return true; +} + +static bool getUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr) +{ + *outStr += fL1S(" << H("); + if (!getRawUshort(tokens, limit, offset, outVal, outStr)) + return false; + *outStr += QString::number(*outVal) + QLatin1Char(')'); + return true; +} + +static bool getRawUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr) +{ + BOUNDS_CHECK(2); + uint val = tokens[offset++]; + val |= (uint)tokens[offset++] << 16; + *outVal = val; + return true; +} + +static bool getUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr) +{ + *outStr += fL1S(" << I("); + if (!getRawUint(tokens, limit, offset, outVal, outStr)) + return false; + *outStr += QString::number(*outVal) + QLatin1Char(')'); + return true; +} + +static bool getRawStr(const ushort *tokens, int limit, int &offset, int strLen, QString *outStr) +{ + BOUNDS_CHECK(strLen); + *outStr += fL1S("L\""); + bool attn = false; + for (int i = 0; i < strLen; i++) { + ushort val = tokens[offset++]; + switch (val) { + case '"': *outStr += fL1S("\\\""); break; + case '\n': *outStr += fL1S("\\n"); break; + case '\r': *outStr += fL1S("\\r"); break; + case '\t': *outStr += fL1S("\\t"); break; + case '\\': *outStr += fL1S("\\\\"); break; + default: + if (val < 32 || val > 126) { + *outStr += (val > 255 ? fL1S("\\u") : fL1S("\\x")) + QString::number(val, 16); + attn = true; + continue; + } + if (attn && isxdigit(val)) + *outStr += fL1S("\"\""); + *outStr += QChar(val); + break; + } + attn = false; + } + *outStr += QLatin1Char('"'); + return true; +} + +static bool getStr(const ushort *tokens, int limit, int &offset, QString *outStr) +{ + *outStr += fL1S(" << S("); + ushort len; + if (!getRawUshort(tokens, limit, offset, &len, outStr)) + return false; + if (!getRawStr(tokens, limit, offset, len, outStr)) + return false; + *outStr += QLatin1Char(')'); + return true; +} + +static bool getHashStr(const ushort *tokens, int limit, int &offset, QString *outStr) +{ + *outStr += fL1S(" << HS("); + uint hash; + if (!getRawUint(tokens, limit, offset, &hash, outStr)) + return false; + ushort len; + if (!getRawUshort(tokens, limit, offset, &len, outStr)) + return false; + const QChar *chars = (const QChar *)tokens + offset; + if (!getRawStr(tokens, limit, offset, len, outStr)) + return false; + uint realhash = ProString::hash(chars, len); + if (realhash != hash) + *outStr += fL1S(" /* Bad hash ") + QString::number(hash) + fL1S(" */"); + *outStr += QLatin1Char(')'); + return true; +} + +static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent); + +static bool getSubBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent, + const char *scope) +{ + *outStr += fL1S("\n /* %1 */ ").arg(offset, 5) + + QString(indent * 4, QLatin1Char(' ')) + + fL1S("/* ") + fL1S(scope) + fL1S(" */"); + uint len; + if (!getUint(tokens, limit, offset, &len, outStr)) + return false; + if (len) { + BOUNDS_CHECK(len); + int tmpOff = offset; + offset += len; + forever { + if (!getBlock(tokens, offset, tmpOff, outStr, indent + 1)) + break; // Error was already reported, try to continue + if (tmpOff == offset) + break; + *outStr += QLatin1Char('\n') + QString(20 + indent * 4, QLatin1Char(' ')) + + fL1S("/* Warning: Excess tokens follow. */"); + } + } + return true; +} + +static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent) +{ + static const char * const tokNames[] = { + "TokTerminator", + "TokLine", + "TokAssign", "TokAppend", "TokAppendUnique", "TokRemove", "TokReplace", + "TokValueTerminator", + "TokLiteral", "TokHashLiteral", "TokVariable", "TokProperty", "TokEnvVar", + "TokFuncName", "TokArgSeparator", "TokFuncTerminator", + "TokCondition", "TokTestCall", + "TokReturn", "TokBreak", "TokNext", + "TokNot", "TokAnd", "TokOr", + "TokBranch", "TokForLoop", + "TokTestDef", "TokReplaceDef" + }; + + while (offset != limit) { + *outStr += fL1S("\n /* %1 */").arg(offset, 5) + + QString(indent * 4, QLatin1Char(' ')); + BOUNDS_CHECK(1); + ushort tok = tokens[offset++]; + ushort maskedTok = tok & TokMask; + if (maskedTok >= sizeof(tokNames)/sizeof(tokNames[0]) + || (tok & ~(TokNewStr | TokQuoted | TokMask))) { + *outStr += fL1S(" << {invalid token %1}").arg(tok); + return false; + } + *outStr += fL1S(" << H(") + fL1S(tokNames[maskedTok]); + if (tok & TokNewStr) + *outStr += fL1S(" | TokNewStr"); + if (tok & TokQuoted) + *outStr += fL1S(" | TokQuoted"); + *outStr += QLatin1Char(')'); + bool ok; + switch (maskedTok) { + case TokFuncTerminator: // Recursion, but not a sub-block + return true; + case TokArgSeparator: + case TokValueTerminator: // Not recursion + case TokTerminator: // Recursion, and limited by (sub-)block length + case TokCondition: + case TokReturn: + case TokBreak: + case TokNext: + case TokNot: + case TokAnd: + case TokOr: + ok = true; + break; + case TokTestCall: + ok = getBlock(tokens, limit, offset, outStr, indent + 1); + break; + case TokBranch: + ok = getSubBlock(tokens, limit, offset, outStr, indent, "then branch"); + if (ok) + ok = getSubBlock(tokens, limit, offset, outStr, indent, "else branch"); + break; + default: + switch (maskedTok) { + case TokAssign: + case TokAppend: + case TokAppendUnique: + case TokRemove: + case TokReplace: + // The parameter is the sizehint for the output. + // fallthrough + case TokLine: { + ushort dummy; + ok = getUshort(tokens, limit, offset, &dummy, outStr); + break; } + case TokLiteral: + case TokEnvVar: + ok = getStr(tokens, limit, offset, outStr); + break; + case TokHashLiteral: + case TokVariable: + case TokProperty: + ok = getHashStr(tokens, limit, offset, outStr); + break; + case TokFuncName: + ok = getHashStr(tokens, limit, offset, outStr); + if (ok) + ok = getBlock(tokens, limit, offset, outStr, indent + 1); + break; + case TokForLoop: + ok = getHashStr(tokens, limit, offset, outStr); + if (ok) + ok = getSubBlock(tokens, limit, offset, outStr, indent, "iterator"); + if (ok) + ok = getSubBlock(tokens, limit, offset, outStr, indent, "body"); + break; + case TokTestDef: + case TokReplaceDef: + ok = getHashStr(tokens, limit, offset, outStr); + if (ok) + ok = getSubBlock(tokens, limit, offset, outStr, indent, "body"); + break; + default: + Q_ASSERT(!"unhandled token"); + } + } + if (!ok) + return false; + } + return true; +} + +QString QMakeParser::formatProBlock(const QString &block) +{ + QString outStr; + outStr += fL1S("\n << TS("); + int offset = 0; + getBlock(reinterpret_cast<const ushort *>(block.constData()), block.length(), + offset, &outStr, 0); + outStr += QLatin1Char(')'); + return outStr; +} + +#endif // PROPARSER_DEBUG + QT_END_NAMESPACE diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h index f8bbe905c3..dfea1ddfdf 100644 --- a/qmake/library/qmakeparser.h +++ b/qmake/library/qmakeparser.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -96,6 +96,10 @@ public: void discardFileFromCache(const QString &fileName); +#ifdef PROPARSER_DEBUG + static QString formatProBlock(const QString &block); +#endif + private: enum ScopeNesting { NestNone = 0, @@ -130,7 +134,7 @@ private: }; bool read(ProFile *pro, ParseFlags flags); - bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar); + void read(ProFile *pro, const QString &content, int line, SubGrammar grammar); ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok); ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len); @@ -144,8 +148,12 @@ private: const ushort *cur, const QString &in); void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount); void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc); + void warnOperator(const char *msg); + bool failOperator(const char *msg); + bool acceptColon(const char *msg); + void putOperator(ushort *&tokPtr); void finalizeTest(ushort *&tokPtr); - void bogusTest(ushort *&tokPtr); + void bogusTest(ushort *&tokPtr, const QString &msg); void enterScope(ushort *&tokPtr, bool special, ScopeState state); void leaveScope(ushort *&tokPtr); void flushCond(ushort *&tokPtr); @@ -153,7 +161,10 @@ private: void message(int type, const QString &msg) const; void parseError(const QString &msg) const - { message(QMakeParserHandler::ParserError, msg); } + { + message(QMakeParserHandler::ParserError, msg); + m_proFile->setOk(false); + } void languageWarning(const QString &msg) const { message(QMakeParserHandler::ParserWarnLanguage, msg); } void deprecationWarning(const QString &msg) const @@ -168,7 +179,7 @@ private: int m_markLine; // Put marker for this line bool m_inError; // Current line had a parsing error; suppress followup error messages bool m_canElse; // Conditionals met on previous line, but no scope was opened - bool m_invert; // Pending conditional is negated + int m_invert; // Pending conditional is negated enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed QString m_tmp; // Temporary for efficient toQString diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 125d074ce3..613e4e90d7 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h index 80e0eec07b..8eeae15dcc 100644 --- a/qmake/library/qmakevfs.h +++ b/qmake/library/qmakevfs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/main.cpp b/qmake/main.cpp index e4b5e6a9cb..27969932bc 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/meta.cpp b/qmake/meta.cpp index 2c3649fcb5..d7aa885541 100644 --- a/qmake/meta.cpp +++ b/qmake/meta.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -94,9 +94,6 @@ QMakeMetaInfo::clear() QString QMakeMetaInfo::findLib(QString lib) { - if((lib[0] == '\'' || lib[0] == '"') && - lib[lib.length()-1] == lib[0]) - lib = lib.mid(1, lib.length()-2); lib = Option::normalizePath(lib); QString ret; diff --git a/qmake/meta.h b/qmake/meta.h index fd03f4e816..a08b946916 100644 --- a/qmake/meta.h +++ b/qmake/meta.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/option.cpp b/qmake/option.cpp index 5af9b100a0..4d20f64d58 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -37,7 +37,7 @@ #include <qregexp.h> #include <qhash.h> #include <qdebug.h> -#include <qsettings.h> +#include <qlibraryinfo.h> #include <stdlib.h> #include <stdarg.h> @@ -215,7 +215,7 @@ Option::parseCommandLine(QStringList &args, QMakeCmdLineParserState &state) QMAKE_VERSION_STR, QT_VERSION_STR, QLibraryInfo::location(QLibraryInfo::LibrariesPath).toLatin1().constData()); #ifdef QMAKE_OPENSOURCE_VERSION - fprintf(stdout, "QMake is Open Source software from Digia Plc and/or its subsidiary(-ies).\n"); + fprintf(stdout, "QMake is Open Source software from The Qt Company Ltd and/or its subsidiary(-ies).\n"); #endif return Option::QMAKE_CMDLINE_BAIL; } else if (arg == "-h" || arg == "-help" || arg == "--help") { @@ -530,15 +530,15 @@ Option::fixString(QString string, uchar flags) //fix separators if (flags & Option::FixPathToNormalSeparators) { - string = string.replace('\\', '/'); + string.replace('\\', '/'); } else if (flags & Option::FixPathToLocalSeparators) { #if defined(Q_OS_WIN32) - string = string.replace('/', '\\'); + string.replace('/', '\\'); #else - string = string.replace('\\', '/'); + string.replace('\\', '/'); #endif } else if(flags & Option::FixPathToTargetSeparators) { - string = string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep); + string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep); } if ((string.startsWith("\"") && string.endsWith("\"")) || @@ -636,7 +636,7 @@ qmakeAddCacheClear(qmakeCacheClearFunc func, void **data) cache_items.append(new QMakeCacheClearItem(func, data)); } -QString qt_libraryInfoFile() +QString qmake_libraryInfoFile() { if (!Option::globals->qmake_abslocation.isEmpty()) return QDir(QFileInfo(Option::globals->qmake_abslocation).absolutePath()).filePath("qt.conf"); diff --git a/qmake/option.h b/qmake/option.h index a4ca8063e0..0ab0365bb3 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -42,7 +42,6 @@ #include <qstring.h> #include <qstringlist.h> #include <qfile.h> -#include <qlibraryinfo.h> QT_BEGIN_NAMESPACE diff --git a/qmake/project.cpp b/qmake/project.cpp index 45773db784..445c5c9bc5 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -124,17 +124,16 @@ QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList> ProString QMakeProject::expand(const QString &expr, const QString &where, int line) { ProString ret; - if (ProFile *pro = m_parser->parsedProBlock(expr, where, line, QMakeParser::ValueGrammar)) { - if (pro->isOk()) { - m_current.pro = pro; - m_current.line = 0; - const ushort *tokPtr = pro->tokPtr(); - ProStringList result = expandVariableReferences(tokPtr, 1, true); - if (!result.isEmpty()) - ret = result.at(0); - } - pro->deref(); + ProFile *pro = m_parser->parsedProBlock(expr, where, line, QMakeParser::ValueGrammar); + if (pro->isOk()) { + m_current.pro = pro; + m_current.line = 0; + const ushort *tokPtr = pro->tokPtr(); + ProStringList result = expandVariableReferences(tokPtr, 1, true); + if (!result.isEmpty()) + ret = result.at(0); } + pro->deref(); return ret; } diff --git a/qmake/project.h b/qmake/project.h index 43f50e7c78..9a5d0e285e 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -78,6 +78,7 @@ public: using QMakeEvaluator::evaluateFeatureFile; using QMakeEvaluator::evaluateConfigFeatures; using QMakeEvaluator::evaluateExpression; + using QMakeEvaluator::propertyValue; using QMakeEvaluator::values; using QMakeEvaluator::first; using QMakeEvaluator::isActiveConfig; diff --git a/qmake/property.cpp b/qmake/property.cpp index 051e05693c..817ae953d5 100644 --- a/qmake/property.cpp +++ b/qmake/property.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -36,6 +36,7 @@ #include <qdir.h> #include <qsettings.h> +#include <qlibraryinfo.h> #include <qstringlist.h> #include <stdio.h> @@ -79,6 +80,7 @@ QMakeProperty::QMakeProperty() : settings(0) m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths); QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths); if (!propList[i].raw) { + m_values[ProKey(name + "/dev")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::DevicePaths); m_values[ProKey(name)] = QLibraryInfo::location(propList[i].loc); name += "/raw"; } @@ -158,6 +160,7 @@ QMakeProperty::exec() ProString pval = value(ProKey(prop + "/raw")); ProString gval = value(ProKey(prop + "/get")); ProString sval = value(ProKey(prop + "/src")); + ProString dval = value(ProKey(prop + "/dev")); fprintf(stdout, "%s:%s\n", prop.toLatin1().constData(), val.toLatin1().constData()); if (!pval.isEmpty() && pval != val) fprintf(stdout, "%s/raw:%s\n", prop.toLatin1().constData(), pval.toLatin1().constData()); @@ -165,6 +168,8 @@ QMakeProperty::exec() fprintf(stdout, "%s/get:%s\n", prop.toLatin1().constData(), gval.toLatin1().constData()); if (!sval.isEmpty() && sval != gval) fprintf(stdout, "%s/src:%s\n", prop.toLatin1().constData(), sval.toLatin1().constData()); + if (!dval.isEmpty() && dval != pval) + fprintf(stdout, "%s/dev:%s\n", prop.toLatin1().constData(), dval.toLatin1().constData()); } return true; } diff --git a/qmake/property.h b/qmake/property.h index a54fe5e43f..e00804967b 100644 --- a/qmake/property.h +++ b/qmake/property.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 4de41d63e6..782151d763 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -12,7 +12,6 @@ SOURCES += project.cpp property.cpp main.cpp \ generators/win32/msvc_vcproj.cpp \ generators/win32/msvc_vcxproj.cpp \ generators/win32/msvc_objectmodel.cpp generators/win32/msbuild_objectmodel.cpp \ - generators/integrity/gbuild.cpp \ generators/win32/cesdkhandler.cpp HEADERS += project.h property.h \ @@ -26,7 +25,6 @@ HEADERS += project.h property.h \ generators/win32/msvc_vcproj.h \ generators/win32/msvc_vcxproj.h \ generators/win32/msvc_objectmodel.h generators/win32/msbuild_objectmodel.h \ - generators/integrity/gbuild.h \ generators/win32/cesdkhandler.h bootstrap { #Qt code @@ -138,8 +136,8 @@ bootstrap { #Qt code SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp mac { SOURCES += qcore_mac.cpp qsettings_mac.cpp - OBJECTIVE_SOURCES += qlocale_mac.mm - LIBS += -framework ApplicationServices + OBJECTIVE_SOURCES += qcore_mac_objc.mm qlocale_mac.mm + LIBS += -framework ApplicationServices -framework CoreServices -framework Foundation } else { SOURCES += qlocale_unix.cpp } diff --git a/qmake/qmake_pch.h b/qmake/qmake_pch.h index d9ab211043..ab40d93682 100644 --- a/qmake/qmake_pch.h +++ b/qmake/qmake_pch.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** 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. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** 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 +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ |