Add initial clang-cl support to Qt

This adds the functionality to build Qt with clang under Windows against
the Microsoft Visual Studio 2015 runtime.

In order to replicate this, a Clang 3.8 build with Visual Studio 2015
Update 1 is needed.

Adds compiler detection to Qt to distinguish correctly the clang compiler
and Windows with Visual Studio.

Clang has some built-in numeric functions, there is no need to use the
Microsoft versions, which also conflict here.

Task-number: QTBUG-50804
Change-Id: Ia4b267a298310ac7d73edf473b12792991249d8a
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
Andreas Holzammer 2016-02-10 13:05:26 +01:00
parent 9e8c84aa14
commit 7e85e7ced7
7 changed files with 97 additions and 13 deletions

View File

@ -34,7 +34,7 @@ set QTDIR=%CD%
if not exist %QTSRC%.gitignore goto sconf if not exist %QTSRC%.gitignore goto sconf
echo Please wait while bootstrapping configure ... echo Please wait while bootstrapping configure ...
for %%C in (cl.exe icl.exe g++.exe perl.exe jom.exe) do set %%C=%%~$PATH:C for %%C in (clang-cl.exe cl.exe icl.exe g++.exe perl.exe jom.exe) do set %%C=%%~$PATH:C
if "%perl.exe%" == "" ( if "%perl.exe%" == "" (
echo Perl not found in PATH. Aborting. >&2 echo Perl not found in PATH. Aborting. >&2
@ -81,6 +81,12 @@ if not "%icl.exe%" == "" (
rem This must have a trailing space. rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32 set tmpl=win32
) else if not "%clang-cl.exe%" == "" (
echo CXX = clang-cl>>Makefile
echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
) else if not "%cl.exe%" == "" ( ) else if not "%cl.exe%" == "" (
echo CXX = cl>>Makefile echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile echo EXTRA_CXXFLAGS =>>Makefile

View File

@ -0,0 +1,24 @@
#
# qmake configuration for win32-clang-msvc2015
#
# Written for Clang 3.8 with Microsoft Visual C++ 2015 Update 1
# Notice: this uses the clang-cl wrapper
#
MSC_VER = 1900
MSVC_VER = 14.0
include(../common/msvc-desktop.conf)
QMAKE_COMPILER += clang_cl llvm
QMAKE_CC = clang-cl
QMAKE_CXX = $$QMAKE_CC
QMAKE_CFLAGS += -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
# Precompiled headers are not supported yet by clang
CONFIG -= precompile_header
load(qt_config)

View File

@ -0,0 +1,34 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake spec 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 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
** 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.
**
** 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$
**
****************************************************************************/
#include "../win32-msvc2005/qplatformdefs.h"

View File

@ -14,6 +14,10 @@ QMKSRC = $(SOURCE_PATH)\qmake
CXX = icl CXX = icl
LINKER = link LINKER = link
CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11
!elseif "$(QMAKESPEC)" == "win32-clang-msvc2015"
CXX = clang-cl
LINKER = link
CFLAGS_EXTRA = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value
!else !else
CXX = cl CXX = cl
LINKER = link LINKER = link
@ -21,13 +25,18 @@ LINKER = link
CFLAGS_EXTRA = /Zc:wchar_t- CFLAGS_EXTRA = /Zc:wchar_t-
! elseif "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2013" ! 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) CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS $(CFLAGS_CRT)
! elseif "$(QMAKESPEC)" == "win32-msvc2015" ! elseif "$(QMAKESPEC)" == "win32-msvc2015" || "$(QMAKESPEC)" == "win32-clang-msvc2015"
CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 /wd4577 $(CFLAGS_CRT) CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 /wd4577 $(CFLAGS_CRT)
! else ! else
! error Unsupported compiler for this Makefile ! error Unsupported compiler for this Makefile
! endif ! endif
!endif # !win32-icc !endif # !win32-icc
!if "$(QMAKESPEC)" != "win32-clang-msvc2015"
CFLAGS_PCH = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch
PCH_OBJECT = qmake_pch.obj
!endif
CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-W3 -nologo -O1 \ -W3 -nologo -O1 \
$(CFLAGS_EXTRA) \ $(CFLAGS_EXTRA) \
@ -41,7 +50,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
-DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY -DQT_NO_STANDARDPATHS -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY -DQT_NO_STANDARDPATHS
CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS) CFLAGS = $(CFLAGS_PCH) $(CFLAGS_BARE) $(CFLAGS)
CXXFLAGS_BARE = $(CFLAGS_BARE) CXXFLAGS_BARE = $(CFLAGS_BARE)
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
@ -129,7 +138,7 @@ QTOBJS= \
first all: qmake.exe first all: qmake.exe
qmake.exe: $(OBJS) $(QTOBJS) qmake.exe: $(OBJS) $(QTOBJS)
$(LINKQMAKE) qmake_pch.obj $(LINKQMAKE) $(PCH_OBJECT)
-copy qmake.exe $(BUILD_PATH)\bin\qmake.exe -copy qmake.exe $(BUILD_PATH)\bin\qmake.exe
clean:: clean::
@ -158,9 +167,9 @@ distclean:: clean
.cxx.obj: .cxx.obj:
$(CXX) $(CXXFLAGS) $< $(CXX) $(CXXFLAGS) $<
$(OBJS): qmake_pch.obj $(OBJS): $(PCH_OBJECT)
$(QTOBJS): qmake_pch.obj $(QTOBJS): $(PCH_OBJECT)
qlibraryinfo.obj: $(BUILD_PATH)\src\corelib\global\qconfig.cpp qlibraryinfo.obj: $(BUILD_PATH)\src\corelib\global\qconfig.cpp

View File

@ -83,6 +83,9 @@
# endif # endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# ifdef __clang__
# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
# endif
# define Q_CC_MSVC (_MSC_VER) # define Q_CC_MSVC (_MSC_VER)
# define Q_CC_MSVC_NET # define Q_CC_MSVC_NET
# define Q_OUTOFLINE_TEMPLATE inline # define Q_OUTOFLINE_TEMPLATE inline
@ -97,7 +100,9 @@
# define Q_UNREACHABLE_IMPL() __assume(0) # define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn) # define Q_NORETURN __declspec(noreturn)
# define Q_DECL_DEPRECATED __declspec(deprecated) # define Q_DECL_DEPRECATED __declspec(deprecated)
# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text)) # ifndef Q_CC_CLANG
# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text))
# endif
# define Q_DECL_EXPORT __declspec(dllexport) # define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport) # define Q_DECL_IMPORT __declspec(dllimport)
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
@ -1177,7 +1182,7 @@
# define QT_WARNING_DISABLE_MSVC(number) # define QT_WARNING_DISABLE_MSVC(number)
# define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_CLANG(text)
# define QT_WARNING_DISABLE_GCC(text) # define QT_WARNING_DISABLE_GCC(text)
#elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 #elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 && !defined(Q_CC_CLANG)
# undef QT_DO_PRAGMA /* not needed */ # undef QT_DO_PRAGMA /* not needed */
# define QT_WARNING_PUSH __pragma(warning(push)) # define QT_WARNING_PUSH __pragma(warning(push))
# define QT_WARNING_POP __pragma(warning(pop)) # define QT_WARNING_POP __pragma(warning(pop))

View File

@ -222,7 +222,7 @@ template <> inline bool mul_overflow(unsigned long long v1, unsigned long long v
# define HAVE_MUL64_OVERFLOW # define HAVE_MUL64_OVERFLOW
#endif #endif
#if ((defined(Q_CC_MSVC) && _MSC_VER >= 1800) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86) #if ((defined(Q_CC_MSVC) && _MSC_VER >= 1800) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r) template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return _addcarry_u32(0, v1, v2, r); } { return _addcarry_u32(0, v1, v2, r); }
# ifdef Q_CC_MSVC // longs are 32-bit # ifdef Q_CC_MSVC // longs are 32-bit
@ -230,7 +230,7 @@ template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigne
{ return _addcarry_u32(0, v1, v2, reinterpret_cast<unsigned *>(r)); } { return _addcarry_u32(0, v1, v2, reinterpret_cast<unsigned *>(r)); }
# endif # endif
#endif #endif
#if ((defined(Q_CC_MSVC) && _MSC_VER >= 1800) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86_64) #if ((defined(Q_CC_MSVC) && _MSC_VER >= 1800) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86_64) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r) template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r)
{ return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); } { return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); }
# ifndef Q_CC_MSVC // longs are 64-bit # ifndef Q_CC_MSVC // longs are 64-bit
@ -239,7 +239,7 @@ template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigne
# endif # endif
#endif #endif
#if defined(Q_CC_MSVC) && (defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_IA64)) #if defined(Q_CC_MSVC) && (defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_IA64)) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
#pragma intrinsic(_umul128) #pragma intrinsic(_umul128)
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
{ {

View File

@ -2,11 +2,17 @@ CORESRC = $(QTSRC)src\corelib
TOOLSRC = $(QTSRC)tools TOOLSRC = $(QTSRC)tools
CONFSRC = $(TOOLSRC)\configure CONFSRC = $(TOOLSRC)\configure
PCH = configure_pch.pch
DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH) DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH)
INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2012" INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2012"
CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 -wd4577 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 -wd4577 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH)
!IF ("$(CXX)" != "clang-cl")
PCH = configure_pch.pch
PCH_OBJECT = configure_pch.obj
CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE)
!ELSE
PCH =
CXXFLAGS = -Wmicrosoft $(CXXFLAGS_BARE)
!ENDIF
LINK = link LINK = link
LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:"configure.intermediate.manifest" LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:"configure.intermediate.manifest"
LIBS = ole32.lib advapi32.lib shell32.lib LIBS = ole32.lib advapi32.lib shell32.lib
@ -71,7 +77,7 @@ OBJECTS = \
qxmlutils.obj \ qxmlutils.obj \
quuid.obj \ quuid.obj \
registry.obj \ registry.obj \
configure_pch.obj $(PCH_OBJECT)
$(TARGET): $(OBJECTS) $(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< $(LINK) $(LFLAGS) /OUT:$(TARGET) @<<