From 226b423a16a7cb312036afa50c0f4ddcfc8bb24f Mon Sep 17 00:00:00 2001 From: henderkes Date: Tue, 14 Apr 2026 23:46:13 +0700 Subject: [PATCH] fix clang build of C++ extensions, update build flags for better toolset support --- TSRM/TSRM.h | 7 ++- win32/build/confutils.js | 116 ++++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 51 deletions(-) diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 80d6cbad04435..ea13552c83747 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -175,9 +175,14 @@ TSRM_API bool tsrm_is_managed_thread(void); #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) #define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element) #define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset))) +#ifdef __cplusplus +#define TSRMLS_MAIN_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; } +#define TSRMLS_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE; } +#else #define TSRMLS_MAIN_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; -#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE; +#endif +#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() #define TSRMLS_CACHE _tsrm_ls_cache diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 0930a86b741ca..0b146d615c907 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3306,7 +3306,7 @@ function toolset_setup_common_cflags() ADD_FLAG("CFLAGS", "/Zc:wchar_t"); } else if (CLANG_TOOLSET) { - ADD_FLAG("CFLAGS", "-Wno-deprecated-declarations"); + ADD_FLAG("CFLAGS", "-Wno-deprecated-declarations -Wno-microsoft-enum-forward-reference"); if (TARGET_ARCH == 'x86') { ADD_FLAG('CFLAGS', '-m32'); } else { @@ -3340,24 +3340,25 @@ function toolset_setup_intrinsic_cflags() /* From oldest to newest. */ var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512"); - if (VS_TOOLSET) { - if ("disabled" == PHP_NATIVE_INTRINSICS) { - ERROR("Can't enable intrinsics, --with-codegen-arch passed with an incompatible option. ") - } + if ("disabled" == PHP_NATIVE_INTRINSICS) { + return; + } - if (TARGET_ARCH == 'arm64') { - /* arm64 supports neon */ - configure_subst.Add("PHP_SIMD_SCALE", 'NEON'); - /* all officially supported arm64 cpu supports crc32 (TODO: to be confirmed) */ - AC_DEFINE('HAVE_ARCH64_CRC32', 1); - return; - } + if (TARGET_ARCH == 'arm64') { + /* arm64 supports neon */ + configure_subst.Add("PHP_SIMD_SCALE", 'NEON'); + /* all officially supported arm64 cpu supports crc32 (TODO: to be confirmed) */ + AC_DEFINE('HAVE_ARCH64_CRC32', 1); + return; + } - if ("no" == PHP_NATIVE_INTRINSICS || "yes" == PHP_NATIVE_INTRINSICS) { - PHP_NATIVE_INTRINSICS = default_enabled; - } + // if --enable-native-intrisics is not specified, it's "no" - enable default + if ("no" == PHP_NATIVE_INTRINSICS || "yes" == PHP_NATIVE_INTRINSICS) { + PHP_NATIVE_INTRINSICS = default_enabled; + } - if ("all" == PHP_NATIVE_INTRINSICS) { + if ("all" == PHP_NATIVE_INTRINSICS) { + if (VS_TOOLSET) { var list = (new VBArray(avail.Keys())).toArray(); for (var i in list) { @@ -3366,46 +3367,61 @@ function toolset_setup_intrinsic_cflags() /* All means all. __AVX__, __AVX2__, and __AVX512*__ are defined by compiler. */ ADD_FLAG("CFLAGS","/arch:AVX512"); - configure_subst.Add("PHP_SIMD_SCALE", "AVX512"); - } else { - var list = PHP_NATIVE_INTRINSICS.split(","); - var j = 0; - for (var k = 0; k < scale.length; k++) { - for (var i = 0; i < list.length; i++) { - var it = list[i].toLowerCase(); - if (scale[k] == it) { - j = k > j ? k : j; - } else if (!avail.Exists(it) && "avx512" != it && "avx2" != it && "avx" != it) { - WARNING("Unknown intrinsic name '" + it + "' ignored"); - } - } - } - if (TARGET_ARCH == 'x86') { - /* SSE2 is currently the default on 32-bit. It could change later, - for now no need to pass it. But, if SSE only was chosen, - /arch:SSE is required. */ - if ("sse" == scale[j]) { - ADD_FLAG("CFLAGS","/arch:SSE"); + } else if (CLANG_TOOLSET) { + ADD_FLAG("CFLAGS","-mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl"); + } + configure_subst.Add("PHP_SIMD_SCALE", "AVX512"); + } else { + var list = PHP_NATIVE_INTRINSICS.split(","); + var j = 0; + for (var k = 0; k < scale.length; k++) { + for (var i = 0; i < list.length; i++) { + var it = list[i].toLowerCase(); + if (scale[k] == it) { + j = k > j ? k : j; + } else if (!avail.Exists(it) && "avx512" != it && "avx2" != it && "avx" != it) { + WARNING("Unknown intrinsic name '" + it + "' ignored"); } } - configure_subst.Add("PHP_SIMD_SCALE", scale[j].toUpperCase()); - /* There is no explicit way to enable intrinsics between SSE3 and SSE4.2. - The declared macros therefore won't affect the code generation, - but will enable the guarded code parts. */ - if ("avx512" == scale[j]) { - ADD_FLAG("CFLAGS","/arch:AVX512"); - j -= 3; - } else if ("avx2" == scale[j]) { - ADD_FLAG("CFLAGS","/arch:AVX2"); - j -= 2; - } else if ("avx" == scale[j]) { - ADD_FLAG("CFLAGS","/arch:AVX"); - j -= 1; - } + } + if (TARGET_ARCH == 'x86') { + /* SSE2 is currently the default on 32-bit. It could change later, + for now no need to pass it. But, if SSE only was chosen, + /arch:SSE is required. */ + if ("sse" == scale[j]) { + ADD_FLAG("CFLAGS", VS_TOOLSET ? "/arch:SSE" : "-msse"); + } + } + configure_subst.Add("PHP_SIMD_SCALE", scale[j].toUpperCase()); + if ("avx512" == scale[j]) { + ADD_FLAG("CFLAGS", VS_TOOLSET ? "/arch:AVX512" : "-mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl"); + j -= 3; + } else if ("avx2" == scale[j]) { + ADD_FLAG("CFLAGS", VS_TOOLSET ? "/arch:AVX2" : "-mavx2"); + j -= 2; + } else if ("avx" == scale[j]) { + ADD_FLAG("CFLAGS", VS_TOOLSET ? "/arch:AVX" : "-mavx"); + j -= 1; + } + if (VS_TOOLSET) { + /* MSVC has no explicit way to enable intrinsics between SSE3 and SSE4.2. + The declared macros won't affect code generation, but will enable + the guarded code parts. */ for (var i = 0; i <= j; i++) { var it = scale[i]; AC_DEFINE(avail.Item(it), 1); } + } else if (CLANG_TOOLSET) { + /* clang supports -m flags for each SSE level and auto-defines + the corresponding __SSE*__ macros. Pass the highest requested + level; clang implicitly enables all lower levels. */ + var clang_flag_map = { + "sse": "-msse", "sse2": "-msse2", "sse3": "-msse3", + "ssse3": "-mssse3", "sse4.1": "-msse4.1", "sse4.2": "-msse4.2" + }; + if (clang_flag_map[scale[j]]) { + ADD_FLAG("CFLAGS", clang_flag_map[scale[j]]); + } } } }