Skip to content

Fix MSVC x86 and MinGW builds#142

Open
BYVoid wants to merge 4 commits intos-yata:masterfrom
BYVoid:fix-msvc-x86-and-mingw-builds
Open

Fix MSVC x86 and MinGW builds#142
BYVoid wants to merge 4 commits intos-yata:masterfrom
BYVoid:fix-msvc-x86-and-mingw-builds

Conversation

@BYVoid
Copy link
Copy Markdown

@BYVoid BYVoid commented Mar 27, 2026

Summary

  • Use _BitScanForward fallback in bit-vector.cc for 32-bit MSVC targets where _BitScanForward64 is unavailable
  • Ad #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 to guard PrefetchVirtualMemory and WIN32_MEMORY_RANGE_ENTRY
  • CMakeLists.txt: Changed if (MINGW) to if (WIN32) so _WIN32_WINNT=_WIN32_WINNT_WIN8 is set for all Windows targets (per luadebug’s suggestion).

Ported from BYVoid/OpenCC#1078.

Test plan

  • Verify CI passes on existing platforms
  • Build with MSVC x86 (Win32) target
  • Build with MinGW toolchain

🤖 Generated with Claude Code

- Use _BitScanForward fallback for 32-bit MSVC targets where
  _BitScanForward64 is unavailable
- Define _WIN32_WINNT=0x0602 in mapper.cc before windows.h to ensure
  PrefetchVirtualMemory and WIN32_MEMORY_RANGE_ENTRY are available on
  MinGW

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread lib/marisa/grimoire/io/mapper.cc Outdated
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0602
#elif _WIN32_WINNT < 0x0602
#undef _WIN32_WINNT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just silently redefining this doesn't seem great. How about #error marisa-trie requires ...?

(Hi Carbo!)

Comment thread lib/marisa/grimoire/io/mapper.cc Outdated
#if (defined _WIN32) || (defined _WIN64)
// Require Windows 8+ for PrefetchVirtualMemory / WIN32_MEMORY_RANGE_ENTRY
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0602
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is set here:

add_compile_definitions(_WIN32_WINNT=_WIN32_WINNT_WIN8)

Maybe it should be set for more than just MINGW?

@luadebug

Copy link
Copy Markdown
Contributor

@luadebug luadebug Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest run was 6 months ago and it does not seems had issues... xmake-io/xmake-repo#8215
MinGW itself has that defined here down below https://github.com/mirror/mingw-w64/blob/93f3505a758fe70e56678f00e753af3bc4f640bb/mingw-w64-headers/include/sdkddkver.h#L23
I just had issue with MinGW but not issue found for Windows, maybe we can promote if (MINGW) to if (WIN32) but I am not sure that is what PR tends to do.
https://cmake.org/cmake/help/v3.8/variable/WIN32.html
Can you try just changing to if(WIN32) and check if that works for windows MSVC x86 @BYVoid

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can promote if (MINGW) to if (WIN32)

Yes, that sounds reasonable.

- mapper.cc: Replace silent _WIN32_WINNT redefinition with #error when
  the value is too low, instead of silently overriding it.
- CMakeLists.txt: Set _WIN32_WINNT for all Windows targets (WIN32),
  not just MinGW, so MSVC also gets the correct definition.

https://claude.ai/code/session_01L3jK8DJupby9nSzWredf95
@BYVoid
Copy link
Copy Markdown
Author

BYVoid commented Mar 27, 2026

after some trials, I believe we must provide an alternative to Windows environments that don't support PrefetchVirtualMemory.

Errors:
https://buildkite.com/bazel/bcr-presubmit/builds/31257/steps/canvas?jid=019d2edb-4a4c-454c-bb38-e9ac6f14c50a

Do you think if we can skip

  if (flags & MARISA_MAP_POPULATE) {
    WIN32_MEMORY_RANGE_ENTRY range_entry;
    range_entry.VirtualAddress = origin_;
    range_entry.NumberOfBytes = size_;
    ::PrefetchVirtualMemory(GetCurrentProcess(), 1, &range_entry, 0);
  }

when _WIN32_WINNT is not defined or less than 0x0602?

@BYVoid BYVoid requested review from jmr and luadebug March 27, 2026 10:48
@jmr
Copy link
Copy Markdown
Contributor

jmr commented Mar 27, 2026

Do you think if we can skip [...] PrefetchVirtualMemory

Yes, that's the equivalent of skipping it when MAP_POPULATE isn't defined, but see below.

when _WIN32_WINNT is not defined

I think this should just be an error. You should define what versions you want to support.

less than 0x0602?

0x0602 is Windows 8. Windows 7 was EOL in 2020 or 2023 depending on how you want to count it.

https://en.wikipedia.org/wiki/Windows_7#:~:text=Extended%20support%20ended%20on%20January%2014%2C%202020%2C%20over,three%20years%20since%20the%20official%20end%20of%20life

Why is this relevant at all?

@jmr
Copy link
Copy Markdown
Contributor

jmr commented Mar 27, 2026

Can you make a PR for the bazel support? Then it could include a .bazelrc that does build:windows --copt=-D_WIN32_WINNT=_WIN32_WINNT_WIN8 like the CMakeLists.txt does.

Instead of requiring _WIN32_WINNT >= 0x0602 (Windows 8) at compile time,
conditionally compile the PrefetchVirtualMemory call so builds targeting
older Windows versions simply skip the prefetch optimization. This also
reverts CMakeLists.txt back to only setting _WIN32_WINNT for MinGW.

https://claude.ai/code/session_01L3jK8DJupby9nSzWredf95
@BYVoid
Copy link
Copy Markdown
Author

BYVoid commented Mar 28, 2026

#143 is the Bazel PR.

In this PR I will keep "Skip PrefetchVirtualMemory when _WIN32_WINNT < 0x0602", because this simple change would make Marisa Trie compatible with older systems, even though they are EOL.

In addition, in some CI environments, _WIN32_WINNT is not correctly set, so I prefer make this PrefetchVirtualMemory optimization optional in order not to block CI.

std::system_category(), "MapViewOfFile");

if (flags & MARISA_MAP_POPULATE) {
#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe move #if outside of if ().

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

- Move #if guard outside the if(flags) block per jmr's suggestion
- Set _WIN32_WINNT for all Windows targets (WIN32) not just MinGW
  per luadebug's suggestion

https://claude.ai/code/session_01L3jK8DJupby9nSzWredf95
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants