Skip to content

Commit

Permalink
Add initial clang-cl support to Qt
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Friedemann Kleint <[email protected]>
  • Loading branch information
aholza committed Feb 11, 2016
1 parent 9e8c84a commit 7e85e7c
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 13 deletions.
8 changes: 7 additions & 1 deletion configure.bat
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ set QTDIR=%CD%
if not exist %QTSRC%.gitignore goto sconf
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%" == "" (
echo Perl not found in PATH. Aborting. >&2
Expand Down Expand Up @@ -81,6 +81,12 @@ if not "%icl.exe%" == "" (
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
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%" == "" (
echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
Expand Down
24 changes: 24 additions & 0 deletions mkspecs/win32-clang-msvc2015/qmake.conf
Original file line number Diff line number Diff line change
@@ -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)
34 changes: 34 additions & 0 deletions mkspecs/win32-clang-msvc2015/qplatformdefs.h
Original file line number Diff line number Diff line change
@@ -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"
19 changes: 14 additions & 5 deletions qmake/Makefile.win32
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,29 @@ QMKSRC = $(SOURCE_PATH)\qmake
CXX = icl
LINKER = link
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
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 /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)
! else
! error Unsupported compiler for this Makefile
! endif
!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 \
-W3 -nologo -O1 \
$(CFLAGS_EXTRA) \
Expand All @@ -41,7 +50,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
-DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -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 = $(CFLAGS)
Expand Down Expand Up @@ -129,7 +138,7 @@ QTOBJS= \
first all: qmake.exe

qmake.exe: $(OBJS) $(QTOBJS)
$(LINKQMAKE) qmake_pch.obj
$(LINKQMAKE) $(PCH_OBJECT)
-copy qmake.exe $(BUILD_PATH)\bin\qmake.exe

clean::
Expand Down Expand Up @@ -158,9 +167,9 @@ distclean:: clean
.cxx.obj:
$(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

Expand Down
9 changes: 7 additions & 2 deletions src/corelib/global/qcompilerdetection.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
# endif

#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_NET
# define Q_OUTOFLINE_TEMPLATE inline
Expand All @@ -97,7 +100,9 @@
# define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn)
# 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_IMPORT __declspec(dllimport)
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
Expand Down Expand Up @@ -1177,7 +1182,7 @@
# define QT_WARNING_DISABLE_MSVC(number)
# define QT_WARNING_DISABLE_CLANG(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 */
# define QT_WARNING_PUSH __pragma(warning(push))
# define QT_WARNING_POP __pragma(warning(pop))
Expand Down
6 changes: 3 additions & 3 deletions src/corelib/global/qnumeric_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,15 @@ template <> inline bool mul_overflow(unsigned long long v1, unsigned long long v
# define HAVE_MUL64_OVERFLOW
#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)
{ return _addcarry_u32(0, v1, v2, r); }
# ifdef Q_CC_MSVC // longs are 32-bit
template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return _addcarry_u32(0, v1, v2, reinterpret_cast<unsigned *>(r)); }
# 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)
{ return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); }
# ifndef Q_CC_MSVC // longs are 64-bit
Expand All @@ -239,7 +239,7 @@ template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigne
# 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)
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
{
Expand Down
10 changes: 8 additions & 2 deletions tools/configure/Makefile.win32
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ CORESRC = $(QTSRC)src\corelib
TOOLSRC = $(QTSRC)tools
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)
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)
!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)
!ELSE
PCH =
CXXFLAGS = -Wmicrosoft $(CXXFLAGS_BARE)
!ENDIF
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"
LIBS = ole32.lib advapi32.lib shell32.lib
Expand Down Expand Up @@ -71,7 +77,7 @@ OBJECTS = \
qxmlutils.obj \
quuid.obj \
registry.obj \
configure_pch.obj
$(PCH_OBJECT)

$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<
Expand Down

0 comments on commit 7e85e7c

Please sign in to comment.