From fe7e8bf28740716efd33d58c799313afcc2a9130 Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Wed, 13 Jun 2018 03:00:31 -0700 Subject: [PATCH 1/3] Patches to build on clang-cl This was mostly: - forward declare struct timeval in pytime (it should have been anyway) - moving struct packing in the correct place - Using a more portable, standard garunteed stringize macro - defining compiler names --- Include/pytime.h | 6 ++++++ .../2018-06-13-03-08-13.bpo-33351.fn4g9Z.rst | 3 +++ Modules/_tracemalloc.c | 15 +++++++++++---- PC/pyconfig.h | 14 ++++++-------- 4 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2018-06-13-03-08-13.bpo-33351.fn4g9Z.rst diff --git a/Include/pytime.h b/Include/pytime.h index 4870a9df5b46c8..24be0892024803 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/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 e07022cce2bc9c..acfd9b8d822fd6 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -67,7 +67,10 @@ static PyThread_type_lock tables_lock; #define DEFAULT_DOMAIN 0 -/* Pack the frame_t structure to reduce the memory footprint. */ +/* Pack the pointer_t structure to reduce the memory footprint. */ +#if defined(_MSC_VER) +#pragma pack(push, 4) +#endif typedef struct #ifdef __GNUC__ __attribute__((packed)) @@ -76,14 +79,18 @@ __attribute__((packed)) uintptr_t ptr; unsigned int domain; } pointer_t; +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* Pack the frame_t structure to reduce the memory footprint on 64-bit - architectures: 12 bytes instead of 16. */ +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 388a3c64f18c1f..0e48bd842a114d 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 */ @@ -172,6 +168,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 */ From 48ff92e0bdd44c263b5d26a7ffe1aa8aee2282f5 Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Wed, 13 Jun 2018 10:53:33 -0700 Subject: [PATCH 2/3] Fix whitespace issue in pytime.h --- Include/pytime.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Include/pytime.h b/Include/pytime.h index 24be0892024803..2c669a5ec45190 100644 --- a/Include/pytime.h +++ b/Include/pytime.h @@ -14,9 +14,9 @@ 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; + /* 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 From a61dad1582953fd41f6c59492ab96487d98d4dfb Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Mon, 9 Jul 2018 10:57:34 -0700 Subject: [PATCH 3/3] Add space in compiler version --- PC/pyconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 0e48bd842a114d..96412587845f6e 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -117,7 +117,7 @@ WIN32 is still required for the locale module. #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]") +#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 */