diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 50dc50a6549340..98faaa14bde05c 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -140,13 +140,21 @@ jobs: win32: arch: win32 buildOpt: + installClang: no testRunTitle: '$(Build.SourceBranchName)-win32' testRunPlatform: win32 win64: arch: amd64 buildOpt: '-p x64' + installClang: no testRunTitle: '$(Build.SourceBranchName)-win64' testRunPlatform: win64 + win64_clang_cl: + arch: amd64 + buildOpt: '-p x64 "/p:CLToolExe=clang-cl.exe" "/p:CLToolPath=C:\Program Files\LLVM\bin"' + installClang: yes + testRunTitle: '$(Build.SourceBranchName)-clang_cl-win64' + testRunPlatform: win64 maxParallel: 4 steps: diff --git a/.azure-pipelines/pr b/.azure-pipelines/pr new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 228f9db4f8ef23..9e82a44e2b896d 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -140,16 +140,25 @@ jobs: win32: arch: win32 buildOpt: + installClang: no testRunTitle: '$(System.PullRequest.TargetBranch)-win32' testRunPlatform: win32 win64: arch: amd64 buildOpt: '-p x64' + installClang: no testRunTitle: '$(System.PullRequest.TargetBranch)-win64' testRunPlatform: win64 winarm64: arch: arm64 buildOpt: '-p arm64' + installClang: no + win64_clang_cl: + arch: amd64 + buildOpt: '-p x64 "/p:CLToolExe=clang-cl.exe" "/p:CLToolPath=C:\Program Files\LLVM\bin"' + installClang: yes + testRunTitle: '$(Build.SourceBranchName)-clang_cl-win64' + testRunPlatform: win64 maxParallel: 4 steps: diff --git a/.azure-pipelines/windows-steps.yml b/.azure-pipelines/windows-steps.yml index f502c40637c310..612591c928ff41 100644 --- a/.azure-pipelines/windows-steps.yml +++ b/.azure-pipelines/windows-steps.yml @@ -12,6 +12,18 @@ steps: Write-Host '##vso[task.setvariable variable=EXTERNALS_DIR]$(Build.BinariesDirectory)\externals' displayName: Update build locations +- powershell: | + (New-Object System.Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/LLVM-9.0.1-win32.exe", "LLVM-win.exe") + Start-Process .\LLVM-win.exe -ArgumentList '/S' -Wait + displayName: Install clang on win32 + condition: and(eq('yes', variables['installClang']), eq('win32', variables['arch'])) + +- powershell: | + (New-Object System.Net.WebClient).DownloadFile("https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/LLVM-9.0.1-win64.exe", "LLVM-win.exe") + Start-Process .\LLVM-win.exe -ArgumentList '/S' -Wait + displayName: Install clang on win64 + condition: and(eq('yes', variables['installClang']), eq('amd64', variables['arch'])) + - script: PCbuild\build.bat -e $(buildOpt) displayName: 'Build CPython' env: diff --git a/Include/pytime.h b/Include/pytime.h index bdda1da2e6b8f2..43eba304c2b89d 100644 --- a/Include/pytime.h +++ b/Include/pytime.h @@ -13,6 +13,12 @@ functions and constants extern "C" { #endif +#if defined(_MSC_VER) + /* Forward declare struct timeval so that clang-cl doesn't complain about it + being a local declaration later on in _PyTime_AsTimeval.*/ + struct timeval; +#endif /* _MSC_VER */ + /* _PyTime_t: Python timestamp with subsecond precision. It can be used to store a duration, and so indirectly a date (related to another date, like UNIX epoch). */ diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index af8099a4078192..df10a0427cd732 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -167,6 +167,15 @@ def _find_exe(exe, paths=None): 'win-arm64' : 'x86_arm64' } +# A map keyed by get_platform() return values to value accepted by +# clang as the triple. +PLAT_TO_LLVM_TARGETS = { + 'win32': 'i686-pc-windows-msvc', + 'win-amd64': 'x86_64-pc-windows-msvc', + 'win-arm32': 'arm-pc-windows-msvc', + 'win-arm64': 'aarch64-pc-windows-msvc', +} + class MSVCCompiler(CCompiler) : """Concrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.""" @@ -198,11 +207,12 @@ class MSVCCompiler(CCompiler) : exe_extension = '.exe' - def __init__(self, verbose=0, dry_run=0, force=0): + def __init__(self, verbose=0, dry_run=0, force=0, use_clang_cl=False): CCompiler.__init__ (self, verbose, dry_run, force) # target platform (.plat_name is consistent with 'bdist') self.plat_name = None self.initialized = False + self.use_clang_cl = use_clang_cl def initialize(self, plat_name=None): # multi-init means we would need to check platform same each time... @@ -224,7 +234,10 @@ def initialize(self, plat_name=None): self._paths = vc_env.get('path', '') paths = self._paths.split(os.pathsep) - self.cc = _find_exe("cl.exe", paths) + if self.use_clang_cl: + self.cc = _find_exe("clang-cl.exe") + else: + self.cc = _find_exe("cl.exe", paths) self.linker = _find_exe("link.exe", paths) self.lib = _find_exe("lib.exe", paths) self.rc = _find_exe("rc.exe", paths) # resource compiler @@ -258,6 +271,16 @@ def initialize(self, plat_name=None): ldflags_debug = [ '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' ] + if self.use_clang_cl: + # Add target for clang + target_flag = "--target=" + PLAT_TO_LLVM_TARGETS[plat_name] + self.compile_options.append(target_flag) + self.compile_options_debug.append(target_flag) + # Remove whole program optimization flags to avoid warnings about + # unrecognized options + self.compile_options.remove('/GL') + ldflags.remove('/LTCG') + ldflags_debug.remove('/LTCG') self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1'] self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1'] @@ -537,3 +560,10 @@ def find_library_file(self, dirs, lib, debug=0): else: # Oops, didn't find it in *any* of 'dirs' return None + + +class ClangMSVCCompiler(MSVCCompiler): + compiler_type = 'clang-cl' + + def __init__(self, verbose=0, dry_run=0, force=0): + MSVCCompiler.__init__(self, verbose, dry_run, force, True) diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py index b5ef143e72c564..2896ce74fee789 100644 --- a/Lib/distutils/ccompiler.py +++ b/Lib/distutils/ccompiler.py @@ -968,6 +968,8 @@ def get_default_compiler(osname=None, platform=None): "Mingw32 port of GNU C Compiler for Win32"), 'bcpp': ('bcppcompiler', 'BCPPCompiler', "Borland C++ Compiler"), + 'clang-cl':('_msvccompiler', 'ClangMSVCCompiler', + "clang-cl for Microsoft Visual C++"), } def show_compilers(): diff --git a/Misc/NEWS.d/next/Build/2018-06-13-03-08-13.bpo-33351.fn4g9Z.rst b/Misc/NEWS.d/next/Build/2018-06-13-03-08-13.bpo-33351.fn4g9Z.rst new file mode 100644 index 00000000000000..0d02f3371e06b4 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-06-13-03-08-13.bpo-33351.fn4g9Z.rst @@ -0,0 +1,3 @@ +Port CPython to build with clang-cl on Windows. + +Patch by Ethan Smith diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index fc91622d3925b8..d2784b1aa88f8e 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -52,11 +52,12 @@ static PyThread_type_lock tables_lock; /* Pack the frame_t structure to reduce the memory footprint on 64-bit architectures: 12 bytes instead of 16. */ +#if defined(_MSC_VER) +#pragma pack(push, 4) +#endif typedef struct #ifdef __GNUC__ __attribute__((packed)) -#elif defined(_MSC_VER) -#pragma pack(push, 4) #endif { /* filename cannot be NULL: "" is used if the Python frame diff --git a/PC/pyconfig.h b/PC/pyconfig.h index b29f63c35bccb1..9989a08f0fa21c 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -94,15 +94,9 @@ WIN32 is still required for the locale module. /* e.g., this produces, after compile-time string catenation, * ("[MSC v.1200 32 bit (Intel)]") * - * _Py_STRINGIZE(_MSC_VER) expands to - * _Py_STRINGIZE1((_MSC_VER)) expands to - * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting - * it's scanned again for macros and so further expands to (under MSVC 6) - * _Py_STRINGIZE2(1200) which then expands to - * "1200" + * The double-stringize hack, a method to get the string version of _MSC_VER */ -#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) -#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X +#define _Py_STRINGIZE(X) _Py_STRINGIZE2(X) #define _Py_STRINGIZE2(X) #X /* MSVC defines _WINxx to differentiate the windows platform types @@ -122,6 +116,8 @@ WIN32 is still required for the locale module. #if defined(_M_X64) || defined(_M_AMD64) #if defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#elif defined(__clang__) +#define COMPILER ("[clang v." _Py_STRINGIZE(__clang_version__) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") #else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #endif /* __INTEL_COMPILER */ @@ -175,6 +171,8 @@ typedef _W64 int ssize_t; #if defined(_M_IX86) #if defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#elif defined(__clang__) +#define COMPILER ("[clang v." _Py_STRINGIZE(__clang_version__) "32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") #else #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") #endif /* __INTEL_COMPILER */ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy