diff --git a/src/Package/Extension/rar.php b/src/Package/Extension/rar.php index 70ea94174..c73c3f77f 100644 --- a/src/Package/Extension/rar.php +++ b/src/Package/Extension/rar.php @@ -63,24 +63,42 @@ public function patchUnrarCpuDetectionForZig(): void } #[BeforeStage('php', [php::class, 'makeForWindows'], 'ext-rar')] - #[PatchDescription('Keep the PHP Windows SDK WINVER/_WIN32_WINNT when unrar os.hpp is included')] + #[PatchDescription('Keep the PHP Windows SDK macros and hide PARSE_SERVER from unrar headers')] public function patchUnrarWindowsVersion(): void { $file = $this->getBuildDir() . '/unrar/os.hpp'; - if (!is_file($file)) { - return; + if (is_file($file)) { + // unrar/os.hpp unconditionally changes WINVER/_WIN32_WINNT to Windows XP. + // PHP's Windows build already defines them for the modern SDK, so keep the + // values the build already selected (this silences the macro warnings). + FileSystem::replaceFileRegex( + $file, + '/^#define WINVER _WIN32_WINNT_WINXP\r?\n#define _WIN32_WINNT _WIN32_WINNT_WINXP/m', + "#ifndef WINVER\n#define WINVER _WIN32_WINNT_WINXP\n#endif\n" + . "#ifndef _WIN32_WINNT\n#define _WIN32_WINNT _WIN32_WINNT_WINXP\n#endif" + ); } - // unrar/os.hpp unconditionally changes WINVER/_WIN32_WINNT to Windows XP. - // PHP's Windows build already defines them for the modern SDK, and the generated - // main/internal_functions.c includes this header before urlmon.h. Mixing SDK - // versions in one TU makes urlmon.h fail with C2059 around PARSEACTION, which - // breaks every spc-max build. Keep the values the build already selected. - FileSystem::replaceFileRegex( - $file, - '/^#define WINVER _WIN32_WINNT_WINXP\r?\n#define _WIN32_WINNT _WIN32_WINNT_WINXP/m', - "#ifndef WINVER\n#define WINVER _WIN32_WINNT_WINXP\n#endif\n" - . "#ifndef _WIN32_WINNT\n#define _WIN32_WINNT _WIN32_WINNT_WINXP\n#endif" + // php_variables.h defines PARSE_SERVER as 5. unrar's os.hpp includes + // shlwapi.h, which includes objbase.h -> urlmon.h, whose PARSEACTION enum + // also has a PARSE_SERVER member. The macro turns that member into + // "5 = (PARSE_MIME + 1)" and breaks main/internal_functions.c on MSVC. + $header = $this->getBuildDir() . '/php_rar.h'; + if (!is_file($header)) { + return; + } + $content = FileSystem::readFile($header); + if (str_contains($content, 'SPC_RAR_PARSE_SERVER_UNDEF')) { + return; + } + $content = str_replace( + '#include "unrar/os.hpp"', + "/* SPC_RAR_PARSE_SERVER_UNDEF: urlmon.h (via shlwapi.h -> objbase.h) declares\n" + . " * PARSE_SERVER, but php_variables.h defines it as a macro. */\n" + . "#ifdef PARSE_SERVER\n#undef PARSE_SERVER\n#endif\n" + . '#include "unrar/os.hpp"', + $content ); + FileSystem::writeFile($header, $content); } }